Per prima cosa, i grossi blocchi di blocchi if/else
sono non facilmente testabili . Ogni nuovo "ramo" aggiunge un altro percorso di esecuzione e quindi aumenta la complessità ciclomatica . Se vuoi testare accuratamente il tuo codice, dovresti coprire tutti i percorsi di esecuzione e ogni condizione richiederebbe di scrivere almeno un altro test (supponendo che tu scriva test piccoli e focalizzati). D'altra parte, le classi che implementano strategie in genere espongono solo 1 metodo pubblico, che è facile da testare.
Quindi, con nidificato if/else
ti ritroverai con molti test per una singola parte del tuo codice, mentre con Strategia avrai pochi test per ciascuna delle strategie più semplici. Con quest'ultimo, è facile avere una copertura migliore, perché è più difficile perdere i percorsi di esecuzione.
Come per estensibilità , immagina di scrivere un framework, in cui gli utenti dovrebbero essere in grado di 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 offrire agli utenti del framework la possibilità di fornire un'implementazione su come calcolare alcune tasse particolari.
Ecco il modello di strategia:
- definisci un'interfaccia, ad es.
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 tuo 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 semplicemente del 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.
L'uso del modello di strategia può migliorare la leggibilità perché, mentre una classe che implementa una determinata strategia in genere dovrebbe avere un nome descrittivo, ad es. USAIncomeTaxCalculator
, if/else
blocchi sono "senza nome", nei casi migliori appena commentati, e i commenti possono mentire. Inoltre, secondo il mio gusto personale, non è possibile leggere più di quel 3% di blocchi di% di fila in una riga, e diventa piuttosto brutto con i blocchi nidificati.
Anche il principio Aperto / Chiuso è molto pertinente, perché, come descritto nell'esempio sopra, Strategia ti permette di estendere una logica in alcune parti del tuo codice ("apri per estensione") senza riscrivere quelle parti ("chiuso per modifica").