In che modo avere troppe variabili di istanza porta a duplicare il codice?

16

In base a Refactoring to Patterns :

When a class is trying to do too much, it often shows up as too many instance variables. When a class has too many instance variables, duplicated code cannot be far behind.

In che modo avere troppe variabili di istanza porta a duplicare il codice?

    
posta q126y 14.11.2015 - 02:30
fonte

4 risposte

20

Avere troppe variabili di istanza non è direttamente correlato 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, è probabile che il programmatore che lo ha scritto non si sia occupato del codice pulito o dei principi SOLID (almeno, non nel momento in cui ha scritto quel codice) , quindi non è improbabile che troverai altri odori di codice come codice duplicato.

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 fare in modo che funzioni, è necessario duplicare una variabile membro e modificare anche quella variabile. Questo potrebbe risultare in una classe con troppe variabili di istanza (più precise: troppe variabili di istanza dall'aspetto molto simile). In una situazione del genere, le variabili di istanza simili potrebbero essere un indicatore per codice ripetuto in altre parti della classe. Tuttavia, come hai notato, questo è un esempio artificiale e non vorrei trarne una regola generale.

    
risposta data 14.11.2015 - 07:09
fonte
11

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

Questa è la classica lezione di calcestruzzo singolo 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 più grosse di side effects .

C'è almeno un'eccezione a questo che non rientra in questa categoria ed è un modo semplice per rimediare a questo. Gli oggetti Immutable non hanno questo problema, perché sono uno stato fisso, non ci sono possibilità di gestione di stati contorti o effetti collaterali.

    
risposta data 14.11.2015 - 03:36
fonte
7

L'affermazione che citi deve essere vista in un contesto specifico.

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

link

Divertente, troverai "troppe variabili di istanza" un buon odore di codice come "troppo 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 qualche tipo di stato dell'oggetto. Gli Stati hanno sempre bisogno di un trattamento attento. È necessario assicurarsi di aver coperto tutte le possibili combinazioni di stati per evitare comportamenti imprevisti. Devi sempre chiaramente ora: quale stato ha il mio oggetto in questo momento? Da questo angolo, molte variabili di istanza possono indicare che la classe è diventata non mantenibile. Può anche indicare che una classe fa troppi lavori, in quanto ha bisogno di così tanti stati.

  2. Ogni variabile di istanza richiede di mantenere la supervisione, che metodi alterano la variabile in che modo. Quindi, all'improvviso, non conosci più tutti i cuochi che stanno cucinando. Uno di loro, programmato stancamente a tarda notte, rovinerà la tua zuppa. Ancora: troppe variabili di questo tipo porteranno a un codice difficile da penetrare.

  3. L'altro lato: troppe poche 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 in qualche modo una cosa molto simile con questo parametro. In questa situazione, il tuo codice inizierà a gonfiarsi. Finirai per scorrere molti schermi su e giù per ottenere alcune cose semplici insieme. Qui, un refactoring può aiutare: introdurre una variabile di istanza e una chiara entrata ad essa. Quindi, libera tutti i metodi.

  4. Ultimo ma non meno importante: se molte variabili di istanza di una classe hanno ciascuna setter e getter ciascuna, allora può indicare che le altre classi non usano questa prima classe nel modo giusto. C'è una discussione su " Perché getter e setter sono cattivi ". L'idea, in breve, è, se una classe Rectangle offre qualche getX() , e dozzine di altre classi usano rectangle.getX() , quindi stai scrivendo un codice che non è robusto contro l'effetto "ripple" (quanto è intorno un codice cambiare influenzare altro codice). Chiedi semplicemente cosa succede se cambi il tipo da int a double ? Secondo questa discussione, molte delle chiamate rectangle.getX() dovrebbero in effetti essere chiamate come rectanlge.calculateThisThingForMe() . Quindi, molto indirettamente, il codice duplicato potrebbe emergere da molte variabili di istanza, dato che molte classi intorno usano molti getter e setter che fanno cose molto simili, cioè cose copiate, che dovrebbero essere spostate meglio all'interno della classe.

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

    
risposta data 14.11.2015 - 10:49
fonte
6

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

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

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

Quindi anche se molte variabili di istanza non sono la causa principale del problema, è un strong "odore" che il problema sta arrivando.

Il linguaggio "non può essere molto indietro" è più debole del dire "deve sicuramente seguire" quindi l'autore non pretende che debba succedere ma alla fine succederà; se è necessario riutilizzare la funzionalità ma non è possibile poiché il codice non è modulare.

    
risposta data 14.11.2015 - 13:10
fonte