Per prima cosa, grossi if/else
blocchi di blocchi non sono facilmente verificabili . Ogni nuovo "ramo" aggiunge un altro percorso di esecuzione e quindi aumenta la complessità ciclomatica . Se vuoi testare a fondo il tuo codice, dovresti coprire tutti i percorsi di esecuzione e ogni condizione richiederebbe di scrivere almeno un altro test (supponendo che tu scriva piccoli test focalizzati). D'altra parte, le classi che implementano strategie in genere espongono solo 1 metodo pubblico, che è facile da testare.
Quindi, con nidificati if/else
finirai con molti test per una singola parte del tuo codice, mentre con Strategia avrai pochi test per ognuna delle molteplici strategie più semplici. Con quest'ultimo, è facile avere una migliore copertura, perché è più difficile perdere i percorsi di esecuzione.
Per quanto riguarda l' estensibilità , immagina di scrivere un framework in cui gli utenti dovrebbero poter iniettare il proprio comportamento. Ad esempio, si desidera creare una sorta di quadro di calcolo delle imposte e si desidera supportare i sistemi fiscali di diversi paesi. Invece di implementarli tutti, vuoi solo dare agli utenti del framework la possibilità di fornire un'implementazione di come calcolare alcune tasse particolari.
Ecco il modello di strategia:
- Definisci un'interfaccia, ad esempio
TaxCalculation
, e il tuo framework accetta istanze di questo tipo per calcolare le tasse
- Un utente del framework crea una classe che implementa questa interfaccia e la passa al framework, fornendo così un modo per eseguire parte dei calcoli
Non puoi fare lo stesso con if/else
, perché ciò richiederebbe la modifica del codice del framework, nel qual caso non sarebbe più un framework. Poiché i framework sono spesso distribuiti in forma compilata, questa potrebbe essere l'unica opzione.
Tuttavia, anche se scrivi solo un codice normale, la strategia è utile perché rende più chiari i tuoi intenti. Dice "questa logica è collegabile e condizionale", cioè possono esserci più implementazioni che possono variare a seconda delle azioni dell'utente, della configurazione o persino della piattaforma.
Utilizzando il modello di strategia può migliorare la leggibilità , perché, mentre una classe che implementa qualche strategia particolare in genere dovrebbe avere un nome descrittivo, ad esempio USAIncomeTaxCalculator
, if/else
i blocchi sono "senza nome", in casi migliori solo commentato, e commenti possono mentire. Inoltre, per i miei gusti personali, avere solo più di 3 if/else
blocchi di fila non è leggibile, e diventa piuttosto male con i blocchi nidificati.
Anche il principio Open / Closed è molto rilevante, perché, come ho descritto nell'esempio sopra, la strategia consente di estendere una logica in alcune parti del codice ("apri per estensione") senza riscrivere quelle parti ("chiuso per modifica" ).