Separazione di logica e dati nel browser game


8

Ci sto pensando da giorni e non sono ancora sicuro di cosa fare. Sto cercando di riformattare un sistema di combattimento in PHP (... mi dispiace.) Ecco cosa esiste finora:

  • Esistono due (finora) tipi di entità che possono partecipare al combattimento. Chiamiamoli giocatori e NPC. I loro dati sono già scritti abbastanza bene.
  • Quando sono coinvolti in un combattimento, queste entità sono avvolte da un altro oggetto nel DB chiamato a Combatant, che fornisce loro informazioni sul combattimento particolare. Possono essere coinvolti in più combattimenti contemporaneamente.
  • Sto cercando di scrivere il motore logico per il combattimento facendo iniettare i combattenti al suo interno.
  • Voglio essere in grado di deridere tutto per i test.

Per separare logica e dati, voglio avere due interfacce / classi base, una essendo ICombatantDatae l'altra ICombatantLogic. I due implementatori di dati saranno uno per gli oggetti reali archiviati nel database e l'altro per i miei oggetti finti.

Ora sto incontrando incertezze nel progettare il lato logico delle cose. Posso avere un implementatore per ciascuno dei giocatori e degli NPC, ma poi ho un problema. Un combattente deve essere in grado di restituire l'entità che avvolge. Questo metodo getter dovrebbe essere parte della logica o dei dati? Sento fortemente che dovrebbe essere nei dati, perché la parte logica viene utilizzata per eseguire il combattimento e non sarà disponibile se qualcuno sta solo cercando informazioni su un combattimento imminente. Ma le classi di dati separano solo il mock dal DB, non il player dall'NPC. Se provo ad avere due classi secondarie dell'implementatore di dati DB, una per ciascun tipo di entità, come posso progettarla mantenendo le mock nel loop? Ho bisogno di una terza interfaccia come IEntityProviderquella che inserisco nelle classi di dati?

Inoltre, con alcune delle idee che ho preso in considerazione, mi sento come se dovessi mettere in atto dei controlli per assicurarmi di non abbinare le cose, come fare la logica per un NPC che avvolge accidentalmente i dati per un giocatore. Ha senso? È una situazione che sarebbe possibile anche se l'architettura fosse corretta o il giusto design lo proibirebbe completamente, quindi non ho bisogno di controllarlo?

Se qualcuno potesse aiutarmi a impaginare un diagramma di classe o qualcosa del genere, mi aiuterebbe molto. Grazie.

modificare

Utile anche da notare, la classe di dati finti non ha davvero bisogno del Entity, dal momento che specificherò direttamente tutti i parametri come le statistiche di combattimento. Quindi forse ciò influirà sul design corretto.


La mia ipotesi Combatant.entitynon è usata durante il combattimento e quindi non dovrebbe esistere. Forse hai bisogno di un'altra classe come quella EntityVsEntityCombatche avvolge la logica di combattimento, contiene Entity <--> Combatantmappature e aggiorna gli Entitystati dopo che il combattimento è finito? Forse qualche informazione in più sulla tua attuale architettura potrebbe aiutare.
Torious

Risposte:


1

Parte del modo in cui mi sono avvicinato a questo in passato è, piuttosto che avere rappresentazioni completamente separate per i giocatori e gli NPC mentre richiedono che entrambi implementino un'interfaccia comune, guidando verso la convergenza della rappresentazione tra loro nella massima misura possibile, come sottoclassandoli da un Charactermodello comune in cui spingo tanto su di loro quanto ha senso generalizzare. Questo aiuta a evitare problemi con l'esecuzione di operazioni NPC sui giocatori e simili rendendo le operazioni più generalmente applicabili, poiché c'è meno tendenza naturale a divergere delle rappresentazioni rispetto a se fossero implementazioni completamente indipendenti. La leva di base del polimorfismo aiuta a gestire i casi che devono divergere (ad esempio, se hai creato il tuoCombatantLogicresponsabile della gestione di ciò che accade quando qualcuno muore, dovresti fare il controllo dei caratteri per assicurarti di aver usato la logica giusta; quindi no, chiedi ai giocatori e agli NPC di implementare die()metodi separati e appropriati ).

Accetto che il tuo Entitysia parte dei dati. Tuttavia, basandomi su ciò che stavo dicendo, in realtà tenderei a rimuovere o limitare il ruolo del tuo CombatantDataa favore del fatto che la logica di combattimento tragga i valori direttamente dai Entity, forse con la CombatantDatasola memorizzazione di valori calcolati specifici per il singolo combattimento. I tuoi modelli di test verrebbero quindi orientati più verso la fornitura di Entitymodelli falsi che verso il popolamento CombatantData. (La CombatantDataduplicazione di molte informazioni da Entityme mi disturba più o meno allo stesso modo di un database denormalizzato. Tuttavia, se credi nella Legge di Demetra, che io appassionatamente non, non vorrai fare le cose nel modo in cui Sto suggerendo. Naturalmente, se credi nella Legge di Demetra, non sono sicuro che tuCombatantDatadovrebbe anche fornire l'accesso al Entity.)


CombatantData non duplica realmente i dati delle entità, include lo stato dell'entità in combattimento, come la salute attuale e gli eventuali effetti di stato su di essa.
Tesserex,

@Tesserex: Ah, ok. Se quello stato non persiste tra i combattimenti, allora è ragionevole. Ignora quella parte, quindi. :) Ha senso il resto di quello che sto dicendo?
caos,
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.