In che modo avere troppe variabili di istanza porta a un codice duplicato?


19

Secondo Refactoring to Patterns :

Quando una classe sta provando a fare troppo, spesso si presenta come troppe variabili di istanza. Quando una classe ha troppe variabili di istanza, il codice duplicato non può essere molto indietro.

In che modo avere troppe variabili di istanza porta a un codice duplicato?


2
In poche parole: le nvariabili booleane, ad esempio, creano uno spazio interno di stati di 2^n. Molto spesso, sebbene il tuo oggetto non abbia molti stati osservabili , ma poiché hai stipato tutto quello stato in un singolo oggetto, internamente devi comunque gestirli tutti.
biziclop,

Risposte:


23

La presenza di troppe variabili di istanza non è direttamente correlata al codice duplicato o viceversa. Questa affermazione, in questa generalità, è falsa. Si possono lanciare due classi separate senza codice duplicato in una classe - che produce una nuova classe con responsabilità non separate e troppe variabili di istanza, ma ancora nessun codice duplicato.

Ma quando trovi una classe con troppe responsabilità nel codice legacy del mondo reale, è molto probabile che il programmatore che lo ha scritto non si preoccupi del codice pulito o dei principi SOLIDI (almeno, non al momento in cui ha scritto quel codice), quindi il suo non è improbabile che ci siano altri odori di codice come codice duplicato lì dentro.

Ad esempio, l'anti-pattern "copia-incolla riutilizzo" viene spesso applicato copiando un vecchio metodo e apportando alcune lievi modifiche ad esso, senza un adeguato refactoring. A volte, per far funzionare tutto ciò, è necessario duplicare una variabile membro e modificarla anche un po '. Ciò potrebbe comportare una classe con troppe variabili di istanza (più preciso: troppe variabili di istanza dall'aspetto molto simile). In una situazione del genere, le variabili di istanza simili potrebbero essere un indicatore di codice ripetuto altrove nella classe. Tuttavia, come hai notato, questo è un esempio artificiale e non ne traggerei una regola generale.


11

Troppe variabili di istanza significano troppo stato. Troppo stato porta a codice duplicato che è solo leggermente diverso per ciascuno degli stati.

Questa è una classica classe concreta che fa troppe cose che dovrebbero essere sottoclassi o composizioni.

Trova alcune classi che hanno troppe variabili di istanza, vedrai che mantengono troppo lo stato e hanno molti percorsi di codice duplicati che sono solo leggermente specializzati per ogni caso, ma così contorti che non possono essere suddivisi in metodi riutilizzabili. Questa è anche una delle fonti side effectspiù importanti.

Esiste almeno un'eccezione a ciò che non rientra in questa categoria ed è un modo semplice per rimediare. Immutablegli oggetti non presentano questo problema, poiché sono uno stato fisso, non vi sono possibilità di gestione contorta dello stato o effetti collaterali.


7

L'affermazione che citi è pensata per essere vista in un contesto specifico.

Secondo la mia esperienza, non posso confermare che "molte variabili di istanza in generale indicano un codice duplicato". Inoltre, si noti che questo appartiene agli "odori di codice" e che ci sono odori presumibilmente contraddittori. Dai un'occhiata qui:

http://c2.com/cgi/wiki?CodeSmell

In modo divertente, troverete che "troppe variabili di istanza" è un buon odore di codice quanto "troppe poche variabili di istanza".

Ma ci sono problemi con le variabili di istanza, che siano troppo poche o troppe:

  1. Ogni variabile di istanza può significare un tipo di stato dell'oggetto. Gli Stati hanno sempre bisogno di un trattamento accurato. È necessario assicurarsi di aver coperto tutte le possibili combinazioni di stati al fine di evitare comportamenti imprevisti. Devi sempre chiaramente ora: quale stato ha il mio oggetto in questo momento? Da questo punto di vista, molte variabili di istanza possono indicare che la classe è diventata non mantenibile. Può anche indicare che una classe fa troppi lavori, poiché ha bisogno di così tanti stati.

  2. Ogni variabile di istanza richiede di mantenere la supervisione, quali metodi modificano la variabile in che modo. Quindi, all'improvviso, non conosci più tutti i cuochi che stanno cucinando. Uno di questi, programmato stancamente a tarda notte, rovinerà la tua zuppa. Ancora: troppe di queste variabili porteranno a codici difficili da penetrare.

  3. Dall'altro lato: troppe variabili di istanza possono far sì che molti metodi debbano gestire le loro informazioni con troppo lavoro e con troppi parametri. Lo senti, se stai dando a molti dei tuoi metodi un certo parametro uguale, e tutti i metodi fanno qualcosa di molto simile con questo parametro. In quella situazione, il tuo codice inizierà a gonfiarsi. Finirai con lo scorrimento di molte schermate su e giù per mettere insieme alcune cose semplici. Qui, un refactoring può aiutare: introdurre una variabile di istanza e un chiaro ingresso ad essa. Quindi, libera tutti i metodi.

  4. Ultimo ma non meno importante: se molte variabili di istanza di una classe hanno il loro setter e getter ciascuna, allora può indicare che altre classi non usano questa prima classe nel modo giusto. C'è una discussione sul " Perché getter e setter sono cattivi ". L'idea in breve è che, se una classe ne Rectangleoffre alcune getX()e ne usano decine di altre rectangle.getX(), allora stai scrivendo un codice che non è robusto rispetto all '"effetto a catena" (fino a che punto una modifica del codice influenza un altro codice). Basta chiedere cosa succede se si cambia il tipo da inta double? Secondo questa discussione, molte rectangle.getX()chiamate dovrebbero in effetti essere chiamate similirectanlge.calculateThisThingForMe(). Quindi, molto indirettamente, il codice duplicato potrebbe emergere da molte variabili di istanza, poiché molte classi intorno usano molti getter e setter che fanno cose molto simili, cioè cose copiate, che dovrebbero essere spostate all'interno della classe.

Molte o poche variabili di istanza rimangono un compromesso permanente, alterando entrambi i modi mentre il software è in crescita.


La citazione da R a P è troppo generica ed è per questo che mi piace questa risposta. Il mio take away è: se esponiamo abbastanza proprietà che un cliente può e vuole prendere e scrivere la propria versione di una data funzionalità - # 4 sopra. Il problema può andare fino in fondo come la composizione dell'oggetto - vedi # 2: lo vedo troppo spesso nel nostro codice. (a) "perché non hanno usato la classe <whatever> (per correggere alcuni di questo stato non organizzato)?" oppure (b) "Perché non hanno fatto una nuova lezione? Non riesco a tenere traccia di tutto." E di sicuro abbiamo diverse classi che duplicano internamente funzionalità per mancanza di una classe coerente.
radarbob,

6

In poche parole: scarsa separazione delle preoccupazioni all'interno del codice, porta a codice che non è modulare, porta a scarso riutilizzo, porta a codice duplicato.

Se non provi mai a ripetere la funzionalità, non otterrai codice duplicato e molte variabili di istanza non saranno un problema.

Se si tenta di ripetere la funzionalità, il codice monolitico, che non è modulare, non può essere riutilizzato. Fa troppo e può fare solo quello che fa. Per fare qualcosa di simile, ma non lo stesso, è "più facile" tagliare e incollare, piuttosto che rompere il codice monolitico. I programmatori di esperienze sanno che il codice duplicato è la strada per l'inferno.

Quindi, sebbene molte variabili di istanza in sé non siano la causa principale del problema, è un forte "odore" che il problema sta arrivando.

Il linguaggio "non può essere molto indietro" è più debole del dire "deve sicuramente seguire", quindi l'autore non sostiene che debba accadere ma alla fine accadrà; se è necessario riutilizzare la funzionalità ma non è possibile in quanto il codice non è modulare.

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.