Che cosa guadagno usando il modello di strategia in questo caso?

3

Ho scritto un programma con Java che riproduce musica semplice. Attualmente gli accordi hanno solo un modo ("strumming pattern") per essere riprodotti. Voglio espandere questo e creare diversi "schemi di strimpellatura" che gli accordi possono usare per suonare i loro appunti.

La classe Chord ha un metodo play() responsabile della riproduzione dell'accordo. Attualmente contiene la logica per l'unico "modello di strimpellio" di come vengono suonate le note.

Per aggiungere nuovi pattern di strumming, l'approccio più semplice è quello di cambiare play() in qualcosa del genere:

void play(int strummingStyle){
    if(strummingStyle == REGULAR_STYLE) playRegular();
    if(strummingStyle == SOMETHING_ELSE_STYLE) playSomethingElse();
    // .. etc
}

Avere un metodo per ogni stile di strumming e parametrizzare il metodo per suonare uno stile specifico.

Tuttavia l'uso del modello di strategia sembra un approccio migliore. Quello che intendo è incapsulare ogni pattern di strumming in una sottoclasse di StrummingPattern e impostare Chord su uno specifico modello di strumming: chord.setStrummingPattern(StrummingPattern pattern); .

play() quindi delegherebbe semplicemente allo schema strumming in questo modo:

void play(){
    pattern.play();
}

Mentre questo sembra come il migliore, più approccio OO - trovo che non riesco a spiegarmi quali sono i reali benefici. Ed è importante per me capire veramente perché sto facendo qualcosa.

Spiega perché usare lo schema della strategia in un caso come questo è un approccio migliore del più ingenuo approccio di un metodo che rappresenta un comportamento. Quali sono esattamente i vantaggi del modello di strategia in questo tipo di situazione? Perché dovrei usarlo?

    
posta Aviv Cohn 09.05.2014 - 02:20
fonte

2 risposte

3

Nel primo esempio è necessario modificare una classe esistente per aggiungere un nuovo comportamento, nella seconda con il modello di strategia è possibile aggiungere nuove funzionalità al sistema aggiungendo nuove classi e senza modificare il codice corrente (o con modifiche minime).

Questo ha molti vantaggi:

  • Minori rischi di violazione delle funzionalità esistenti
  • Classi più piccole rispetto alle classi che crescono e crescono
  • Meglio per il lavoro di squadra, pensa in N programmatori ognuno aggiungendo nuove "strumms" allo stesso tempo con i due approcci
  • I tuoi sistemi sono più estensibili, in futuro puoi rendere pubblica questa API e altre persone possono aggiungere nuovi elementi (accordi, strumms) al tuo sistema

In termini di SOLID, la seconda soluzione è più Open-Close e, di conseguenza, le classi risultanti sono più Single responsability.

Utilizza SOLID, GRASP o altri principi OO come coesione e accoppiamento, pensa nel costo dell'aggiunta di nuove funzionalità, pensa nel costo di comprendere il sistema per un nuovo programmatore come strumenti per valutare i tuoi progetti e imparare a decidere PERCHÉ progettare è meglio o no rispetto ad altri. Gli schemi spesso offrono buone soluzioni o puntatori (spesso no) è necessario affidarsi a più principi fondamentali di OO per valutare e sapere PERCHÉ, sei nella buona direzione se "senti" che ha bisogno di questo Perché, è meglio non usare i modelli che usare poi ciecamente.

    
risposta data 09.05.2014 - 03:01
fonte
2

"Tuttavia usare il modello di strategia sembra un approccio migliore"

Sì. :)

Il tuo istinto ha ragione su questo.

In OO, vuoi evitare quel tipo di "se questo, fai questo, se lo fai", la logica, perché il sistema di tipi gestisce quello per te in modo molto elegante. (In realtà ho un'avversione per se ... poi la logica in generale, perché mentre la logica si dirama, il cervello mi fa sempre più male).

(Un corollario, se stai controllando i tipi con if blah instanceof Blah , allora probabilmente dovrai pensare più duramente al tuo design OO, perché stai tradendo il polimorfismo e sbircia il tipo sottostante. ha bisogno di fare, e il chiamante dovrebbe sapere come chiamarlo.)

Il vantaggio principale del modello di strategia sta sfruttando l'aspetto di dispatch dinamico della lingua per fare il blocco "se ... allora" per te. Quindi devi solo assicurarti che le tue classi di strategia siano corrette e che il consumatore ne faccia correttamente il metodo play() . Si adatta meglio alla complessità, perché è possibile inserire nuove classi di strategia nel tempo. Il test è più facile, perché è tutto ben disaccoppiato.

...

Se vuoi convincerti, fallo in entrambe le direzioni. Scrivi un esempio con 5 alternative come blocco di "if ... thens" e un altro esempio con 5 alternative nel modello di strategia.

Quindi scrivi test unitari al 100% di copertura per entrambi i casi.

;)

    
risposta data 09.05.2014 - 02:57
fonte

Leggi altre domande sui tag