La strategia dell'anatra

Nel primo capitolo di Head First - Design Patterns si tratta il pattern Strategy a partire dalla progettazione di una gerarchia di classi che descrivono il comportamento di diversi tipi di anatre.

Il problema é quello di dare alla gerarchia una robustezza tale da permetterle di reggere agevolemente a cambiamenti futuri delle specifiche di progetto.

Il pattern Strategy definisce una famiglia di algoritmi, li incapsula, e li rende intercambiabili. Strategy fa un modo che l'algoritmo cambi indipendentemente dal client che lo usa.

Nel corso del capitolo vengono citati tre importanti principi, che riporto qui a seguire.

Il fatto che di costante nello sviluppo software sia solo il cambiamento conduce al seguente principio di progettazione: identifica gli aspetti dell'applicazione che cambiano e separali da quelli che non mutano.

Un altro importante principio: programma verso un interfaccia e non verso una implementazione. Questo permette una maggior astrazione del codice e quindi un miglior adattamento del codice al cambiamento.

Un terzo principio: preferisci la composizione all'ereditarietà. Permette molta più flessibilità, dato che permette di cambiare il comportamento di una classe a runtime.

Detto questo, vediamo le specifiche del nostro progetto.

Vogliamo gestire una gerarchia di anatre, in modo da poter gestire classi che rappresentano sia animali veri e propri che oggetti come un anatra di gomma o un anatra da richiamo.

L'idea é che alcuni algoritmi che potrebbero sembrare scontati nella nostra gerarchia (il volare dell'anatra, nel nostro esempio) in realtà non lo sono.

Nell'implementazione originale, ogni nostra anatra poteva volare, emettere un verso (quack!) e nuotare. Creando nuove classi derivate, abbiamo cozzato contro una variazione della progettazione originale: esistono anatre che non emettono versi e anatre che non volano.

Abbiamo quindi rifattorizzato la classe di base per riflettere questo cambiamento: l'anatra generica si appoggia su classi esterne che implementano la strategia della specifica anatra.

Avremo quindi una gerarchia di classi basate in Duck, la classe astratta da cui tutte le nostre anatre derivano, e una gerarchia per ogni strategia che Duck utilizza.

Nel nostro caso abbiamo una interfaccia FlyBehavior per la strategia di volo e QuackBehavior per la strategia di starnazzamento.

Nei post seguenti vedremo il codice per implementare questa soluzione.

Nessun commento:

Posta un commento