I parametri opzionali sono utili o un ostacolo alla manutenzione dell'applicazione? [chiuso]


14

Come indicato nel titolo, sono utili parametri opzionali, come quelli usati in C # o sono un ostacolo alla manutenzione dell'applicazione e dovrebbero essere evitati in quanto possono rendere il codice più difficile da capire?


3
Dichiarazione di non responsabilità: qualsiasi funzionalità linguistica nelle mani sbagliate può essere abusata. Se una lingua lo implementa in modo intelligente, e questa funzionalità linguistica non si sovrappone troppo con una funzionalità linguistica esistente in modo noioso, allora vanno bene, in effetti abbastanza utili. Python ha alcuni parametri di impacchettamento / disimballaggio dei parametri e altri "trucchi" dei parametri (trucchi in senso buono, non in senso Perl).
Giobbe

Prova a scrivere un'app in C # che si interfaccia a Excel senza utilizzare parametri opzionali. Questo dovrebbe rispondere alla tua domanda oltre ogni ragionevole dubbio.
Dunk

Risposte:


22

I parametri opzionali, secondo la mia esperienza, sono stati una buona cosa. Non li ho mai trovati confusi (almeno non più confusi della funzione reale), dal momento che posso sempre ottenere i valori predefiniti e sapere come viene chiamato.

Un uso per loro è quando devo aggiungere un altro parametro a una funzione che è già in uso generale, o almeno nell'interfaccia pubblica. Senza di loro, dovrei rifare la funzione originale per chiamarne una che ha un altro argomento e che può diventare davvero vecchia se finissi per aggiungere argomenti più di una volta.


1
+1 Ed è utile con metodi sovraccarichi che aggiungono un argomento come new Circle(size, color, filled, ellipseProportions)dove sizee colorsono richiesti e il resto è predefinito.
Michael K,

15

In generale, se hai spesso bisogno di molti / parametri opzionali, le tue funzioni stanno facendo troppo e dovrebbero essere suddivise. Probabilmente stai infrangendo SRP (Single Responsibility Principle).

Cerca i parametri che possono essere raggruppati, ad esempio (xey, diventano un punto).

Questi flag di parametri opzionali sono predefiniti? Se stai usando flag, la funzione dovrebbe essere divisa.

Questo non vuol dire che non dovresti mai avere parametri opzionali, ma in generale più di uno o due parametri suggeriscono un odore di codice.

Potrebbe anche essere un indizio che la funzione, in realtà, dovrebbe essere una classe, con i parametri opzionali cambiati in proprietà e i parametri richiesti fanno parte del costruttore.


1
+1 per stare attenti. Qualsiasi funzione, non importa quanto buona, può essere abusata.
Michael K,

3
Questo è un ottimo consiglio per la produzione di codice ravioli troppo ingegnerizzato in cui gli utenti dell'API devono utilizzare almeno 6 classi e 15 funzioni per rendere possibile anche la cosa più semplice.
dsimcha,

1
@dsimcha, come lo ottieni da quello che ho scritto? Wow. Spiega per favore? Sarebbe altrettanto male progettare avere una "super funzione" che è ciò che ottieni quando hai molti parametri opzionali. Leggi i principi di progettazione SOLID e scrivi il codice testabile. Preferibilmente usando TDD. Quindi torna indietro e prova a spiegarmi che ridurre i parametri nelle funzioni è una cosa negativa.
CaffGeek,

1
Il codice testabile è carino, ma lo è anche un'API pulita e utilizzabile che non è eccessivamente granulosa o dettagliata e non classifica le classi di calzascarpe in situazioni in cui una funzione è l'astrazione corretta. Credo nel principio della responsabilità unica con responsabilità definite ad alto livello di astrazione. Se le responsabilità sono definite a un livello troppo basso, le singole unità diventano troppo semplificate in modo tale che le loro interazioni siano eccessivamente complesse.
dsimcha,

1
@dsimcha, ti manca il punto. Le singole unità dovrebbero rimanere singole unità e non essere raggruppate in un'unica funzione. Ciò non significa che siano tutte funzioni accessibili al pubblico. Sei API è il gateway per il codice e dovrebbe essere pulito e conciso. Una funzione con diversi parametri opzionali non è né pulita, né concisa. Tuttavia, sovraccaricare una singola funzione con parametri logici è molto più chiaro. Ad esempio, ci sono funzioni in molte API in cui due parametri sono opzionali, ma è richiesto l'uno o l'altro. Cosa è chiaro a riguardo quando entrambi sono contrassegnati come facoltativi?
CaffGeek,

4

I parametri opzionali vanno bene

In genere la giustificazione è che a) sai di avere molti argomenti possibili per il tuo metodo ma non vuoi sovraccaricare per paura di ingombrare l'API, oppure b) quando non conosci tutti i possibili argomenti ma tu non voglio forzare l'utente a fornire un array. In ogni caso i parametri opzionali vengono in soccorso in modo pulito ed elegante.

Ecco alcuni esempi:

1. Si desidera evitare il sovraccarico e non si desidera specificare un array

Dai un'occhiata a printf () da C, Perl, Java ecc. È un ottimo esempio della potenza dei parametri opzionali.

Per esempio:

printf("I want %d %s %s",1,"chocolate","biccies");

printf("I want %d banana",1);

Nessun sovraccarico, nessuna matrice, semplice e intuitivo (una volta acquisiti i codici di formato stringa standard). Alcuni IDE ti diranno anche se la tua stringa di formato non corrisponde ai tuoi parametri opzionali.

2. Si desidera consentire l'uso dei valori predefiniti e tenerli nascosti all'utente del metodo

sendEmail ( "test@example.org");

Il metodo sendEmail rileva la mancanza di vari valori essenziali e li riempie usando valori predefiniti definiti (soggetto, corpo, cc, ccn ecc.). L'API è mantenuta pulita, ma flessibile.

Una nota su troppi parametri

Tuttavia, come altri hanno affermato, avere troppi parametri obbligatori in un metodo indica che probabilmente hai qualcosa di sbagliato nel tuo design. Ciò è particolarmente vero se condividono lo stesso tipo in quanto possono essere scambiati dallo sviluppatore per errore portando a risultati strani in fase di esecuzione:

String myMethod(String x, String y, String z, String a, int b, String c, int d) {}

è un candidato ideale per il refactoring di Introduce Parameter Object da creare

String myMethod(ParameterObject po) {}

class ParameterObject {
  // Left as public for clarity
  public String x;
  public String y;
  ... etc

}

Questo a sua volta può portare a un design migliore basato su un modello Factory con una specifica fornita come oggetto parametro.


1
funzioni di formattazione delle stringhe come printf sono l'eccezione alla regola, si potrebbe sostenere che mentre usano un elenco illimitato di parametri opzionali, è più come l'argomento che è un array che come parametri opzionali, nonostante come sia implementato.
CaffGeek,

@Chad Ho adattato la mia risposta per meglio distinguere tra parametri opzionali e quando si trasformano in un odore di codice (come hai detto nella tua risposta).
Gary Rowe,

@Gary Rowe, troppi parametri opzionali sono anche cattivi nella maggior parte dei casi.
CaffGeek,

@Chad sono d'accordo, ma la maggior parte delle lingue non fornisce un modo per specificare un limite al numero di argomenti opzionali, quindi è un approccio tutto o niente. Sei costretto a lasciarlo applicare al tuo metodo e, ovviamente, se il tuo metodo ha a che fare con 500 variabili, dovrà sicuramente essere sottoposto a refactoring.
Gary Rowe,

@Gary Rowe, cosa intendi con "la maggior parte delle lingue non fornisce un modo per specificare un limite al numero di argomenti opzionali"? Nella maggior parte delle lingue le contrassegni come tali o non fornisci loro valori quando chiami la funzione, ma l'intestazione della funzione ha ancora i parametri definiti. Certo, in alcune lingue puoi aggiungere tutti i parametri che desideri dopo aver inserito quelli definiti, ma non credo sia il tipo di parametri opzionali di cui stiamo parlando qui. (a parte l'eccezione del formato stringa)
CaffGeek

2

Uno dei problemi con i parametri predefiniti in C # (sto pensando che DoSomething sia vuoto (int x = 1)) è che sono costanti. Ciò significa che se si modifica il valore predefinito, sarà necessario ricompilare tutti gli utenti di tale chiamata del metodo. Mentre questo è abbastanza facile da fare ci sono occasioni in cui questo è pericoloso.


1

Dipende da cosa sta facendo il tuo codice. Se ci sono valori predefiniti sensibili, allora dovresti usare parametri opzionali ma se non ci sono valori predefiniti ragionevoli, l'aggiunta di parametri opzionali renderà il tuo codice più complicato. In molti casi i parametri opzionali sono un modo semplice per eludere i controlli zero e tagliare la logica di ramificazione. Javascript non ha parametri opzionali ma esiste un modo per emularli con || (logico o) e lo uso sempre quando faccio cose relative al database perché se l'utente non fornisce alcun valore, sostituisco i miei valori con l'aiuto di || che mi fa risparmiare la fatica di scrivere un sacco di istruzioni if ​​then.


1

I parametri opzionali sono un ottimo modo per rendere le cose semplici cose semplici e complicate possibili contemporaneamente. Se esiste un chiaro ragionevole default che la maggior parte degli utenti vorrà, almeno in casi di utilizzo rapido e sporco, non dovrebbero scrivere la piastra di caldaia per specificarlo manualmente ogni volta che chiamano la tua funzione. D'altra parte, se le persone potrebbero avere una buona ragione per volerlo cambiare, allora deve essere esposto.

L'uso di una classe è IMHO una soluzione terribile, in quanto verbosa, inefficiente e incoerente con il tipico modello mentale di ciò che fa una classe. Una funzione è l'astrazione perfetta per un verbo, cioè fare qualcosa e tornare. Una classe è l'astrazione giusta per un sostantivo, cioè qualcosa che ha uno stato e può essere manipolato in diversi modi. Se il primo dovrebbe essere il modello mentale dell'utente API, non renderlo una classe.


1

Il problema con gli argomenti opzionali è che le persone tendono a nascondere sempre più (e più) argomenti alla funzione invece di estrarre il codice rilevante in una nuova funzione. Questo è portato all'estremo in php . Per esempio:

bool array_multisort ( array &$arr [, mixed $arg = SORT_ASC
                      [, mixed $arg = SORT_REGULAR [, mixed $... ]]] )

1

I parametri opzionali sono sostanzialmente un modo diverso di sovraccaricare una funzione. Quindi questo in sostanza si riduce a: "sovraccaricare una funzione è male"?


1

Inizialmente ho adorato questa funzionalità in Python e l'ho usata per "estendere" i metodi già utilizzati. E sembrava carino e facile, ma tornò presto; perché quando ho aggiunto un parametro opzionale, questo stava modificando il comportamento di un metodo esistente su cui si basava il vecchio client e in un modo che non era stato rilevato dai casi di unit test esistenti. Fondamentalmente farlo è infrangere il principio aperto chiuso; il codice è aperto per l'estensione ma chiuso per modifica. Quindi credo che usare questa funzione per modificare il codice esistente non sia una buona idea; ma va bene se usato dall'inizio


0

Penserei che sarebbe meglio sovraccaricare una funzione con firme diverse (cioè parametri) piuttosto che usare parametri opzionali.


Perché? Penso che sia più pulito se riesci a combinare un sacco di metodi sovraccaricati in un metodo usando parametri predefiniti se tutti i metodi hanno la stessa funzionalità di base
Amit Wadhwa,

Puoi pensarlo. Non sono uno che pensa che Microsoft faccia tutto nel modo giusto, ma se tu fossi preciso, allora non vedrei mai sovraccarichi quando si usa il framework .NET, solo un'enorme firma di funzione - come nel vecchio VB6.
HardCode,
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.