Che cos'è un argomento di output, come indicato nel codice pulito di Martin?


14

A pagina 45 del codice pulito di Robert C. Martin: un manuale di agile software artigianale, Martin scrive che gli argomenti di output dovrebbero essere evitati. Ho difficoltà a comprendere il significato di "argomento di output" e il motivo per cui dovrebbero essere evitati.

L'esempio di Martin per un argomento di output appendFooter(s);chiama la funzione public void appendFooter(StringBuffer report). Il suo miglioramento del codice èreport.appendFooter();

Forse è dovuto alla mancanza di un contesto di codice, ma non vedo come l'utilizzo di argomenti di output sia considerato una codifica scadente. Qualcuno potrebbe spiegare il concetto o fornire ulteriori esempi di codice per capirlo?

La seguente funzione sarebbe anche considerata un esempio di codice impuro dal suddetto principio?

int[] numberArray = {3, 5, 7, 1};
sortArray(numberArray);

Se quanto sopra è una violazione del principio di Martin di non usare argomenti di output, sarebbe meglio avere un oggetto che ha un array come campo e una funzione che può essere chiamata per ordinare l'array?

ObjectWithArrayField numberArray = new ObjectWithArrayField(3, 5, 7, 1);
numberArray.sort();

Risposte:


11

Bob Martin sta semplicemente parlando di leggibilità .

Il problema con l' appendFooteresempio è che se trovi la linea di codice appendFooter(s)da qualche parte in un programma, non è immediatamente ovvio se quella chiamata prende scome input e la aggiunge da qualche parte, o se sè appena passata per prendere l' output di quella funzione. A dire il vero, è necessario controllare la documentazione della funzione. Una chiamata come report.appendFooter(), tuttavia, evita quel problema: è molto più ovvio ora cosa succede.

Nota, tuttavia, Bob Martin non dice "mai e poi mai usare argomenti di output", dice "in generale, dovresti evitarlo, perché ti aiuterà a mantenere il tuo codice un po 'più pulito". Quindi questa non è una regola di culto del carico che bisogna seguire alla cieca.

Sorti metodi per matrici e raccolte standard sono leggermente diversi. Avere il sortmetodo una funzione membro di ciascun tipo di dati dell'array standard avrebbe alcuni inconvenienti dal punto di vista del progettista del linguaggio, ad esempio avere un metodo come Array.sortpermette di mantenerlo nella libreria standard, al di fuori del runtime Java. Ma se si crea un tipo di raccolta individuale che deve essere ordinato a volte, l'aggiunta sortcome funzione membro potrebbe essere davvero un'idea migliore rispetto a metterla in una classe separata.


2
sortArray(numberArray), ovviamente, ordina numberArraysul posto. Oppure crea una copia di numberArray, ordina la copia e restituisce la copia ordinata senza alterare numberArrayaffatto?
8bittree,

@ 8bittree: questo è vero, ma non è questo il punto di discussione qui - un sort()metodo di un contenitore può funzionare anche sul posto, senza usare un "argomento di output". Quindi, solo perché sortArray(numberArray)è un metodo sul posto non è assolutamente un motivo che giustifichi il "modulo dell'argomento di output".
Doc Brown,

1
Il mio punto era più che non è del tutto ovvio cosa sortArray(numberArray)stia facendo. Può essere ovvio se non restituisce lo stesso tipo che accetta, quindi deve essere in atto. Ma senza vedere il tipo restituito, o se il tipo restituito corrisponde al tipo di input, non è chiaro senza guardare la definizione.
8bittree,

1
@ 8bittree: Ok, mi hai preso, ho rimosso la dichiarazione in gioco dalla mia risposta. Tuttavia, il problema descritto non svanisce utilizzando una funzione membro - anche una funzione membro "ordinamento" potrebbe comportarsi in questo modo.
Doc Brown,

11

Si tratta di utilizzare un meccanismo inaspettato per restituire un valore dalla funzione, che di solito è il risultato di fare troppo nella funzione o di avere responsabilità disallineate. Di gran lunga, il modo migliore per comunicare il risultato di una funzione è usare il valore di ritorno. Spero sia evidente. Nei linguaggi orientati agli oggetti, il secondo metodo migliore è quello di mutare l'oggetto.

Tra queste due opzioni, ci sono così tanti modi chiari e ovvi per comunicare il risultato di una funzione che se mai ti ritrovi a voler mutare gli argomenti come unico mezzo, qualcosa è andato storto nella tua architettura. Devi riorganizzare le tue responsabilità di classe in modo che chi esegue la mutazione possieda i dati in primo luogo.

L'unica eccezione è per algoritmi molto generici. Ad esempio, un algoritmo di ordinamento potrebbe essere legittimamente separato dai contenitori che ordina, se può essere applicato genericamente a qualsiasi tipo di contenitore usando la sua interfaccia pubblica. Una funzione one-shot appendFooternon ha questa scusa.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.