Diffida YAGNI e considera questa risposta a una domanda simile che asserisce che I pattern non sono blocchi predefiniti .
Il Pattern stato GoF risolve un problema di selezione di un oggetto comportamentale singolo per rappresentare una funzionalità di classe.
Nel frattempo, il GoF Composite Pattern risolve un problema di combinazione di più oggetti comportamentali da rappresentare una funzionalità di classe.
Su questa base, i due modelli sono progettati per due obiettivi quasi opposti. Uno schema cerca di estrapolare un solo oggetto comportamentale, mentre l'altro modello cerca di combinare più oggetti comportamentali.
Ovviamente potresti trovare uno scopo per ognuno di loro in qualche parte del tuo programma per risolvere i diversi problemi, ma è molto difficile vedere come potresti ottenere benefici dal provare a usarli insieme per risolvere il problema stesso .
In base alla tua descrizione, sembra che sia necessario il pattern Composite o il pattern State, ma probabilmente non entrambi (ancora), e probabilmente non entrambi insieme (almeno non direttamente).
Pensa a quante variazioni di comportamento / logica hai bisogno dal modello di stato, rispetto a quanto del tuo comportamento può essere semplicemente strutturato come dati.
Pattern stato
- Se hai molta logica dipendente dallo stato nelle tue classi
Component
(ad esempio, comportamento che segue regole / algoritmi / ecc diversi), allora considera di abbandonare il modello composito.
- La logica dipendente dallo stato in un singolo
Component
suggerisce che questi componenti hanno un'identità molto debole e non dovrebbero essere trattati come componenti perché lo stato non appartiene al componente, ma disattiva grandi porzioni del suo comportamento.
- Questi componenti potrebbero contenere anche campi / dati correlati che potrebbero essere comuni a tutti gli stati; quelli potrebbero essere separati in semplici oggetti di dati dal comportamento specifico dello stato (ricordate che il modello di stato riguarda il comportamento e non i dati).
- Potresti anche avere alcuni metodi di "aiuto" comuni in ogni componente il cui comportamento non è specifico dello stato, che potrebbe essere spostato in una classe comune.
- Considera come apparirà il tuo codice se ridistribuisci tutta la logica del componente in
State
classi, eventualmente passando gli oggetti dati in essi.
- Se una determinata classe
State
inizia a sembrare troppo grande o assume troppe responsabilità, puoi applicare un modello composito solo a quello stato particolare.
Motivo componente
- Se la maggior parte delle differenze tra i tuoi stati sono basate su dati (ovvero informazioni che potresti ragionevolmente includere in una tabella di ricerca, una struttura JSON / XML o anche un database), quindi prendere in considerazione la demolizione le classi
State
- Quando 'stato' è solo una descrizione di un set di dati, è sufficiente una semplice rappresentazione come una variabile
enum
che può fungere da chiave per quel set di dati.
- Le variazioni nel comportamento basate sui dati potrebbero essere definite in una mappa semplice o in una struttura simile a un dizionario mediante una variabile di stato.
- Ogni variazione potrebbe essere un oggetto dati di riferimento che definisce regole / vincoli e parametri ai quali i componenti devono obbedire. (ad esempio, un oggetto parametro passato in ogni componente e utilizzato per informare la logica di quei componenti).
Nota finale (in qualche modo non correlata): Diffida dei nomi delle classi che sembrano entità . I nomi di classe utili sono spesso quelli che qualcuno che legge il tuo codice può riguardare immediatamente o alcuni aspetti comportamentali di un programma o un requisito funzionale.
Nomi come Player
non ti dicono nulla su cosa debba essere responsabile di un oggetto Player
; il vero pericolo è che inevitabilmente porta gli sviluppatori verso una mentalità di tipo inside-the-box verso il design; a sua volta, ciò si traduce spesso in God Object s che diventano responsabili per fare tutto che potrebbe teoricamente riguardare a un giocatore.