Come si combinano il pattern di stato e il pattern del componente?

3

Supponiamo di avere una classe Player con le classi PhysicsComponent , InputComponent e StandingState , DuckingState .

La classe Player non ha una funzione di input, la InputComponent lo fa. Ma quando cambiamo gli stati in DuckingState , ad esempio, il comportamento della funzione di input cambia. Quindi, come è impostato?

a) la classe Player ha una variabile current_state , che a sua volta ha una variabile per ciascun componente. Ciò creerebbe molte classi aggiuntive: StandingStatePhysicsComponent , DuckingStatePhysicsComponent , ecc., Poiché dovresti "sovrascrivere" la funzione di input, ad esempio, dovresti farlo nella classe di componente corrispondente, che ha quel metodo.

b) la classe Player ha una variabile current_state e una variabile per ciascun componente. Ciò sarebbe possibile passando un lambda a ciascun componente quando lo stato cambia, che viene eseguito sul metodo update di quel componente.

c) La classe Player ha una variabile per ogni componente, che a loro volta hanno una variabile current_state (Questo ha un senso per me, dal momento che ogni componente avrebbe il suo stato ).

Sono sulla buona strada?

    
posta Post Self 15.04.2017 - 08:44
fonte

1 risposta

5

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.

    
risposta data 15.04.2017 - 11:04
fonte

Leggi altre domande sui tag