Gli sviluppatori di software sono bravissimi a riconoscere i modelli. Forse è un’abilità intrinseca che ci attira verso questa professione. O forse è il processo di scrittura del software che sviluppa questa abilità. In entrambi i casi, il “non ripetersi” (DRY) è un’applicazione naturale di questa abilità.
Tuttavia, la ripetizione in sé non è il nemico che questo principio fa sembrare.
- Non ripetersi
- A volte ripeti te stesso
- Domande da porre
- È un singolo pezzo di conoscenza che è stato duplicato, o è solo un’infrastruttura che sembra simile?
- Quante volte è stata ripetuta questa cosa?
- Ridurre la duplicazione ora renderà più difficile personalizzare i singoli casi in futuro?
- Se riduco questa duplicazione, qual è il rapporto tra la dimensione dell’astrazione e il numero di parametri che prenderà?
- Conclusione
Non ripetersi
Per quanto intuitivo possa essere il “non ripetersi”, The Pragmatic Programmer lo riassume così:
Ogni pezzo di conoscenza deve avere una singola, univoca, autorevole rappresentazione all’interno di un sistema.
Non è difficile immaginare i vantaggi di ridurre o eliminare la ripetizione.
- Meno duplicazione significa meno codice da mantenere. E se il miglior codice è nessun codice, questa sembra una buona cosa.
- Un’unica fonte di verità elimina la possibilità che le cose non siano sincronizzate. Qualche regola di business è cambiata? Aggiornatela in un solo posto e il gioco è fatto.
- Il codice è riutilizzabile. Avete un processo che è condiviso da tre cose, e ne state aggiungendo una quarta? La maggior parte del lavoro è già stato fatto.
A volte ripeti te stesso
Il troppo zelo nel ridurre la duplicazione apparente può creare più problemi di quanti ne risolva. Dico “duplicazione apparente” perché a volte le cose che sembrano simili in realtà non sono correlate. Per esempio, due strutture dati con proprietà e tipi identici possono essere le stesse strutturalmente ma non semanticamente.
Una strategia comune per ridurre il codice duplicato è quella di fattorizzare le parti comuni e nasconderle dietro un’astrazione. Ma un effetto collaterale indesiderato di questo è che accoppia qualsiasi cosa usi l’astrazione. Qualsiasi cambiamento nell’astrazione influenza tutti i suoi consumatori. E allo stesso modo, l’astrazione può aver bisogno di essere piegata per adattarsi ai requisiti di un solo consumatore.
Questo aumento dell’accoppiamento viene anche con una diminuzione della flessibilità. Diciamo che avete un processo che è usato in tre posti. È quasi lo stesso in tutti e tre i posti, con solo alcune importanti differenze. Quindi implementate il processo come un singolo modulo che prende alcuni parametri per coprire le differenze.
Modificare il processo per uno solo di questi casi d’uso è ora impossibile: qualsiasi cambiamento in uno ha effetto su tutti e tre. Certo, si possono aggiungere altri parametri (o casi speciali!) man mano che i casi d’uso divergono. Ma diventerà rapidamente impossibile distinguere le parti importanti del processo dall’infrastruttura che separa i casi d’uso.
Domande da porre
Quando rifattorizzo il codice esistente o scrivo nuovo codice che può essere potenzialmente duplicato, mi chiedo:
È un singolo pezzo di conoscenza che è stato duplicato, o è solo un’infrastruttura che sembra simile?
Quindi hai rovistato nel CSS e hai trovato una classe che ha gli stili che vuoi. Questa probabilmente non è una ragione sufficiente per evitare di definire un’altra classe.
Quante volte è stata ripetuta questa cosa?
Fino a quando una cosa veramente ridondante appare almeno tre volte, sarei molto scettico su qualsiasi riduzione delle ripetizioni che aumenta la complessità.
Ridurre la duplicazione ora renderà più difficile personalizzare i singoli casi in futuro?
C’è qualcosa di soddisfacente nel rifattorizzare un mucchio di codice copia-e-incolla in qualcosa di più snello e riutilizzabile. Ma bloccare il codice così strettamente che ogni cambiamento introdurrebbe casi speciali non è un buon compromesso.
Se riduco questa duplicazione, qual è il rapporto tra la dimensione dell’astrazione e il numero di parametri che prenderà?
Librerie e framework sono ottimi perché forniscono codice riutilizzabile con relativamente pochi parametri per la personalizzazione. Ma immaginate una funzione specifica per la presentazione di una finestra di dialogo che è cresciuta e ora accetta 20 parametri. Qualsiasi beneficio di riduzione delle ripetizioni che esisteva quando aveva 2 parametri non c’è più.
Conclusione
Come per molti principi di sviluppo del software, “non ripetersi” è una linea guida più che un mantra.