Setter o costruttore per molte variabili? [duplicare]

4

Ho una classe con 30 variabili (è un modulo di domanda), quindi mi chiedo quale sia la migliore pratica per organizzare la creazione della classe.

Devo usare un enorme costruttore:

MyClass mc = new MyClass(a, b, c, d)

O setter:

MyClass mc = new MyClass();
mc.setA(a);
mc.setB(b);
mc.setC(c);
mc.setD(d);

Qual è la migliore pratica in OOP per tale situazione? Ho visto una domanda simile, ma ora non ho bisogno di immutabilità.

    
posta Dracontis 14.06.2012 - 23:05
fonte

6 risposte

17

C'è una terza opzione che è la più idiosa orientata agli oggetti

La cosa migliore da fare è utilizzare il modello Builder .

La classe ha un costruttore no-arg predefinito e tu imposti tutti i parametri richiesti e poi chiami .build() o .materialize() o qualche metodo con nome appropriato per convalidare e finalizzare la costruzione dell'oggetto e ottenere un riferimento a l'oggetto completato.

Questo può essere usato con molto successo anche con il modello Fluent API design.

Ecco un esempio su come applicare un'adesione all'API del modello Builder per costruire solo oggetti validi . Il post del blog riguarda Java, ma si applica a qualsiasi tipo di linguaggio Object Oriented che supporta le interfacce. Rende molto facile sapere cosa deve fare dopo con il completamento automatico anche in un IDE.

Non sono un grande fan del pattern Fluent API perché può essere maltrattato molto facilmente, e quando si abusa del metodo il concatenamento rende molto difficile diagnosticare le eccezioni, ma in questo caso particolare è molto appropriato.

    
risposta data 14.06.2012 - 23:48
fonte
21

La principale differenza tra i tuoi 2 esempi è che l'utente della classe è costretto a usare il costruttore ma non è costretto a impostare il suo stato tramite metodi set.

Dovresti inserire tutti gli argomenti nel costruttore che configurerà l'istanza nello stato corretto. Altri metodi di "impostazione" dovrebbero essere facoltativi.

Quello che farei nel tuo caso è identificare all'interno delle tue 30 variabili temi comuni che di per sé possono essere suddivisi in DTO. Quindi potresti avere invece (per esempio):

MyClass mc = new MyClass(personInfo, companyInfo, salaryInfo);

In aggiunta potresti voler controllare se la tua classe sta facendo troppo e se puoi limitare l'uso dello stato interno creando classi di componenti più piccole invece di avere una classe grande.

    
risposta data 14.06.2012 - 23:34
fonte
7

La risposta dipende da come usi la classe ...

  • Se vuoi che la tua classe sia immutabile, dovrai utilizzare i parametri del costruttore.

  • Se vuoi che la tua classe sia deserializzabile con i (de) serializzatori basati sulla relizzazione, avrai bisogno di un costruttore e setter predefiniti.

  • Se la tua classe non dovrebbe essere immutabile e vuoi che i consumatori siano in grado di cambiare tutte le proprietà durante la vita degli oggetti, allora dovrai aggiungere setter in ogni caso (o aggiungere metodi di modifica, che potrebbero sembra meno semplice per i consumatori).

  • Se si utilizza il metodo di costruzione e proprietà predefinito, è necessario assicurarsi che gli utenti non possano invalidare lo stato dell'oggetto impostando in un ordine imprevisto, che i valori predefiniti siano validi e che tutti i setter controllino le cose come intervalli prima di applicare le modifiche.
    Se hai due (o più) proprietà dipendenti, o incapsulali in una classe, o assicurati che se uno di essi è impostato (es. X è impostato), cambia il valore dell'altro (ad es. Il valore di Y) se (Y) è corrente il valore non va insieme al nuovo valore (di X).

Inoltre, considera se la tua classe dovrebbe essere una sola classe:

Se ha 30 parametri, potresti interrompere il principio di incapsulamento OO - dove ogni classe fa una cosa e fa tutto per quell'unica cosa.

Forse dovresti usare composizione di alcune classi o, se hai molti parametri comuni tra le classi, forse hai bisogno di una o più classi verticali che gestiscono un aspetto specifico e può agire su più classi (utilizzando reflection o utilizzando classi aggiuntive in un modello di visitatore ).

    
risposta data 15.06.2012 - 01:10
fonte
0

Vorrei andare con l'enorme costruttore. È il più semplice Se ogni chiamata al costruttore utilizza parametri diversi (cioè, si finirebbe per passare un sacco di null), si costruiscono più costruttori. L'idea di base è mantenere il codice al minimo; renderlo il più semplice possibile. Se hai bisogno di ottenere valori di impostazione fantasiosi e i setter sarebbero più semplici, usali.

C'è qualcosa di sciatto su troppi parametri, quindi potresti voler vedere se dovresti passare oggetti che contengono diversi valori di parametro. Non sforzarti su questo, ma se hai 15 parametri, scommetto che troverai un modo più semplice per farlo.

Troppi parametri sono cattivi, ma troppi setter insensati non sono neanche buoni; non c'è una risposta giusta . Devi scegliere il minore di due tonchi. Questo parla dei setter meglio di me.

    
risposta data 14.06.2012 - 23:39
fonte
0

Vorrei chiederti se davvero costruirai davvero questo oggetto gigante, o sarà sempre caricato da un database?

Non vedo alcun motivo per avere un oggetto così grande costruito con valori provenienti dal codice.

Se questa cosa viene sempre salvata e caricata da un database o da un file, assegnagli un semplice costruttore predefinito e concentrati su come ottenere il mapping del database degli oggetti o la serializzazione corretta.

    
risposta data 14.06.2012 - 23:57
fonte
0

Supponendo che tu non sia in una lingua che rende conveniente scrivere parametri con nome (ad es. Python o Common Lisp), devi considerare se i tuoi oggetti sono considerati di sola lettura o di lettura-scrittura. Se si tratta del primo, è necessario impostare i valori dal costruttore, ma in caso contrario dipende solo da chi ha setter (o dall'equivalente della propria lingua). Dato che hai a che fare con 30 variabili, dovrei davvero prendere in considerazione l'utilizzo di qualcosa che ti permetta di evitare di dover scrivere costruttori con così tanti argomenti. Anche 10 sarebbero troppi per la sanità mentale ...

    
risposta data 15.06.2012 - 00:21
fonte

Leggi altre domande sui tag