L'ereditarietà del contesto, come mostrato dall'esempio Duck di Head First Design Patterns, è irrilevante per il modello strategico?


10

In Head First Design Patterns insegna il modello di strategia usando un esempio Duck in cui diverse sottoclassi di Duck possono essere assegnate un comportamento particolare in fase di esecuzione. Dalla mia comprensione, lo scopo del modello di strategia è quello di cambiare il comportamento di un singolo oggetto in fase di esecuzione, eppure stanno usando l'eredità di Anatra per cambiare il comportamento di vari tipi di Anatra.

Modello di strategia

Rilevanza?

L'ereditarietà del contesto di Duck è irrilevante per il modello di strategia o la variazione dei tipi di Duck e anche il variare dei loro comportamenti è una buona ragione per impiegare il modello di strategia? Le situazioni in cui è necessario variare costituiscono entrambe una buona ragione per utilizzare il modello di strategia? Perché dovrebbero includere questo come esempio di modello di strategia?

Un esempio più semplice

Potrei semplificare ulteriormente questo esempio semplicemente avendo una classe Duck (nessuna classe derivata)? Quindi, quando si implementa un oggetto anatra, è possibile assegnare comportamenti diversi in base a determinate circostanze che non dipendono dal proprio tipo di oggetto. Ad esempio: FlyBehavior cambia in base al tempo o QuackBehavior cambia in base all'ora del giorno o alla fame di un'anatra. Mi rendo conto che questo risolverebbe un problema diverso rispetto a quello del libro, ma quello che sto cercando è un esempio di modello di strategia pertinente su cui fare affidamento.

Il mio esempio sopra costituirebbe anche il modello di strategia?

Modificare:

Sono riuscito a trovare 2 esempi di schemi strategici più semplici che aderiscono più strettamente all'essere solo schemi strategici senza ereditarietà del contesto: Hunter.java e solver.py .

Risposte:


7

Sì, penso che tu sia sulla buona strada. La classe che utilizza il modello di strategia non deve essere una sottoclasse. Il modello di strategia è un'alternativa all'ereditarietà per il riutilizzo del codice. Ciò ritorna al confronto ancora più ampio tra eredità e composizione.

Da Design Patterns: Elements of Reusable OOP a cui useresti i pattern strategici

  • Evitare un'esplosione di sottoclassi (a causa di combinazioni di comportamenti)
  • Se è necessario scambiare il comportamento in fase di esecuzione

Se hai usato l'ereditarietà per implementare comportamenti Quack e Fly, risulteresti con tutte queste sottoclassi per rappresentare tutte le combinazioni di comportamenti.

  • FlyableQuackableDuck
  • FlyableSqeakableDuck
  • FlyableMuteDuck
  • NoFlyQuackableDuck
  • NoFlySqueakableDuck
  • NoFlyMuteDuck

Avere così tante sottoclassi rende più difficile il mantenimento, motivo per cui in questo caso viene favorito il modello di strategia. Hai solo bisogno di due proprietà che incapsulano Flyability e Quackability e puoi mescolarle e abbinarle senza creare nuove classi.

Hai già menzionato il beneficio di runtime di se il tempo ha cambiato la proprietà Fly dell'anatra potrebbe essere sostituita con un oggetto NoFly a causa delle condizioni.

Ciò è coerente con il consiglio di favorire la composizione rispetto all'eredità, quando possibile.


1

Potrei semplificare ulteriormente questo esempio semplicemente avendo una classe Duck (nessuna classe derivata)? Quindi, quando si implementa un oggetto anatra, è possibile assegnare comportamenti diversi in base a determinate circostanze che non dipendono dal proprio tipo di oggetto.

Certamente. Per l'ispirazione, dai un'occhiata a Head First Object-Oriented Analysis and Design . C'è una "Rick's Guitars" che mostra un'esplosione di sottoclassi (musicali) di strumenti . Per ovviare a tutto questo comportamento variabile è racchiuso in una classe di "specifica", osservando il principio di incapsulare ciò che varia .

Fabbrica astratta - Costruzione basata sul contesto

Ecco lo schema . A proposito, nota che usa la strategia stessa.

Concentrandosi sul concetto, non sull'implementazione ... Potresti avere una "WeatherFactory" che costruisce oggetti di specifica basati su condizioni di sole o pioggia, ecc.

Potresti avere "fabbriche di fabbriche" per costruire quelle cose "NoFlyInFogQuackableMallard". E in effetti, questo è ciò che riguarda il modello della Fabbrica Astratta. Quindi forse una DuckFactory per creare tipi di anatre generici, quindi una WeatherFactory per dargli un comportamento nebbioso specifico per il tipo di anatra.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.