È una buona idea sperimentare con modelli di design?

7

Ho letto molto sui diversi modelli di design, i loro pro, contro, l'uso principale ecc. Tuttavia, mi piace sperimentare e provare a inventare le mie modalità di implementazione (anche se non sono le migliori). Ora sto affrontando un problema con l'implementazione del mio sistema componente Entity.

Nonostante i pro di questo modello voglio fare alcune delle cose a modo mio, ad esempio:

1.) I componenti sono racchiusi in interfacce più grandi per la manipolazione dei dati. Nella maggior parte dei casi leggo che i componenti ECS devono contenere solo dati e che i sistemi sono i loro principali manipolatori. Nel mio sistema intendo utilizzare classi wrapper per i componenti

Piccolo esempio: diciamo che vogliamo avere un componente Sprite, che rappresenta la componente visiva di ogni entità nel gioco. L'ho avvolto nella classe RenderableEntity che può essere un componente di un'entità e ha funzioni e variabili aggiuntive.

2.) Non uso un sistema per ogni tipo di componente.

Ancora un esempio del motore di gioco: Abbiamo un CollidableEntity, che viene inserito in una struttura di dati spaziali e che esegue i controlli di collisione, ma per RenderableEntity non esiste un sistema che lo gestisca (presumo che siamo in 2D adesso). Ragionare? Voglio che l'utente abbia la potenza di rendere gli sprite di ogni entità, a causa dell'ordine specifico o utilizzando diversi lotti.

3.) Le entità possono avere più di 1 componente dello stesso tipo e non vengono utilizzati set di bit per verificare se il sistema è interessato a una determinata entità. I componenti sono assegnati ai sistemi al momento della loro creazione tramite il tipo di dati.

Piccolo codice:

template<class DataType>
DataType* createComponent(GameEntity* mainEntity)
{
    //Create it via default constructor
    DataType* component = new DataType();

    //Add it to the back of the component vector
    mainEntity->_entityComponents.emplace_back(component);

    //Assign it to system
    ECS::assignToSystem<T>(component);

    //Return it to access its functions
    return component;
}

La funzione assignToSystem fa quanto segue: controlla se è il tipo di dati specificato nella nostra mappa e in caso contrario aggiunge il componente al sistema e da questo momento il sistema è il manutentore del componente. Anche i sistemi di gioco sono collegati a determinati tipi di dati tramite una funzione e assomiglia a questo:

class ColliderSystem:public ECS::System
{
    void assignSystem() override
    {
        ECS::assignSystemToComponent<CollidableEntity>(this);
    }
};

Puoi dirmi se è una buona idea sperimentare determinati schemi e provare a fare le cose a modo tuo? Soprattutto mi interessa perché voglio usare questo approccio nel mio lavoro di laurea e mi chiedo se sarà un problema se "infrangerò le regole" di alcuni schemi. Inoltre, cosa ne pensi dei miei "cambiamenti", ci sono dei contro? Grazie.

    
posta Pins 16.10.2017 - 20:59
fonte

5 risposte

13

Le persone hanno sperimentato diversi meccanismi per implementare un modello di progettazione in passato con risultati diversi. Ad esempio, la definizione di singleton è che esiste un'unica istanza di una classe per l'intera applicazione. Non c'è nulla in quella definizione che richiede di implementarlo con un accessorio statico, anche se è così che viene scritto l'esempio nel libro GoF. Gente che usa componenti come il framework Spring lascia che il contenitore dei componenti garantisca che ci sia solo un'istanza e che un riferimento a tale istanza sia iniettato ovunque sia necessario accedere.

Questo esempio porta a pochi punti:

  • Se ciò che stai facendo è fondamentalmente diverso dal modello, chiamalo qualcosa di diverso. Non c'è niente di peggio di due persone che usano le stesse parole che parlano di concetti diversi. Dopo di ciò succede solo la confusione.
  • Se quello che stai facendo è seguire lo schema, assicurati che le tue differenze stiano effettivamente risolvendo un problema. Essere diversi solo per essere diversi non è utile 9 volte su 10.
  • "giocare" con i dettagli di implementazione può aiutarti a capire meglio il modello e perché il codice di esempio ha lo stesso aspetto.
  • Unire tutti gli schemi in un unico progetto porta a un pasticcio incomprensibile. Usa semplicemente ciò che devi usare.

Alla fine della giornata, nessun utente elogerà il tuo uso giudizioso del modello del peso mosca o addirittura saprà che hai usato un modello di decoratore lì da qualche parte. I modelli sono chiamati così perché sono soluzioni comuni a problemi comuni che hanno implementazioni molto simili. Molte volte i dettagli dell'implementazione sono meno importanti del concetto che l'ha ispirato. Assicurati solo che il tuo codice sia comprensibile a qualcun altro o persino al tuo futuro di sé per 3 mesi.

Non ho intenzione di predicare, ma ti incoraggerò a guardare l'impatto di ciò che stai facendo nel modo più obiettivo possibile. Gli utenti si preoccupano solo che l'applicazione / gioco / strumento / ecc. lavori. Gli sviluppatori del tuo team si preoccupano se riescono a capirlo e a risolverlo quando trovano cose che non funzionano. Ogni volta che si discosta dalla norma, aumenta la quantità di tempo necessario per comprendere il codice. Rendilo abbastanza noioso e il tuo team di sviluppo riscriverà tutto in modo che sia più familiare.

    
risposta data 16.10.2017 - 22:20
fonte
11

Non ci sono.

I modelli di progettazione non sono elementi costitutivi. Se stai provando a "sperimentare" con loro, probabilmente stai tentando di applicarli in situazioni che non hanno alcun senso.

Invece, dovresti sperimentare cercando di costruire un'ampia varietà di programmi che risolvono una vasta gamma di problemi. In tal modo, troverai varie tecniche che hai usato in alcuni programmi hanno somiglianze con altri programmi, e può essere applicabile a entrambi. Quelle somiglianze sono dove il concetto di modelli di progettazione è sorto, ma non come elementi costitutivi, ma come terminologia.

A meno che tu non conosca i problemi che i modelli nominati sono stati riconosciuti utili a risolvere, non sarai in grado di riconoscerli e sapere quale schema è utile. L'unico modo per imparare questi problemi è affrontare una vasta gamma di domini problematici.

Lo metto in un altro modo

I modelli di progettazione sono come l'equivalente del software di grucce per travetti . Gli hangar di Joist sono pezzi di metallo forgiato che usi per attaccare insieme i membri delle strutture. Allegare i travetti all'impalcatura è un'attività comune, e per anni tutti lo farebbero comunque, finché un individuo intraprendente non ha capito che si trattava di un'attività comune e di un hardware costruito per svolgere il lavoro in modo rapido ed efficace.

Se un carpentiere sul posto di lavoro ha chiesto "è una buona idea sperimentare con i ganci dei travetti?" saranno colpiti in testa con un 2x4. Come i modelli di design, i ganci travetti sono un mezzo per un fine ed è importante capire quale sia il loro scopo. Non crei un disegno in modo da utilizzare ganci travetti, ma usi i ganci perché sono utili nella creazione di giunti strutturali robusti.

Una conoscenza completa del catalogo Simpson Strong-Tie sarebbe inutile per qualcuno a meno che non sia già in grado di visualizzare la maggior parte di come una struttura in legno si riunisca in primo luogo. Allo stesso modo con i modelli di progettazione del software, per prima cosa è necessario essere in grado di immaginare come costruire prima una soluzione completa.

    
risposta data 16.10.2017 - 21:40
fonte
1

I pattern sono un aiuto per raggiungere il tuo obiettivo applicando un approccio progettuale che si è dimostrato idoneo a raggiungere uno scopo specifico.

Certo, sei libero di sperimentare:

  • Molto spesso, guardando più da vicino il nuovo design, potresti scoprire che si tratta di una combinazione di diversi pattern esistenti.
  • A volte, però, potresti scoprire il modo in cui la tua nuova invenzione ha alcuni difetti nascosti. In genere, si tratta di dipendenze aggiuntive e indesiderate.
  • Ma a volte avrai davvero qualcosa di nuovo e adatto.

Attenzione però: il lavoro di laurea richiede disciplina e precisione. Quindi non chiamare il tuo nuovo modello come un modello esistente: i revisori potrebbero interpretarlo come una conoscenza insufficiente piuttosto che creatività.

Quindi, se hai qualcosa di nuovo, dagli un nuovo nome e esponilo nel tuo rapporto di laurea usando un modello di design comprovato come:

risposta data 16.10.2017 - 23:09
fonte
1

Tratterò le parti specifiche della tua domanda relative all'ECS. Ci sono già ottime risposte per la domanda più generale.

Components are wrapped into bigger interfaces for data manipulation. In most of the cases i read that ECS components must contain only data and the systems are their main manipulators. In my system I intend to use a wrapper classes for the components

Ho iniziato a fare la stessa cosa in origine quando ho iniziato perché l'aspetto più estraneo di ECS che sfidava tutte le mie nozioni di OOP come l'occultamento e l'incapsulamento delle informazioni era l'idea che i componenti fossero dati grezzi. Ho anche iniziato a fare cose come avere alcuni componenti ereditati da un'interfaccia astratta e ancora cercando di applicare cose come il polimorfismo a livello di componente.

Man mano che il mio sistema si evolveva, in realtà ho scoperto che si trattava sempre più di un ostacolo. I miei sistemi volevano accedere agli interni dei componenti in modi di basso livello per essere in grado di attraversarli e trasformarli in parallelo e, allo stesso modo, trasformarli individualmente con la logica scalare. Mi sono anche reso conto sempre più che non avevo bisogno del polimorfismo attraverso l'ereditarietà. Un ECS funziona fondamentalmente attraverso la digitazione anatra dello stesso livello di flessibilità che si ha con i modelli C ++, senza richiedere alcuna gerarchia di ereditarietà formale da definire. Se qualcosa ha un componente di movimento, può spostarsi.

È possibile ridurre l'ambito dei campi componenti visibili ai sistemi e ottenere comunque informazioni che nascondono in questo modo limitando il numero di sistemi che possono trattare un componente come qualcosa di più che opaco al fine di mantenere invarianti. Per alcuni componenti potrebbe avere senso solo che un singolo sistema sia in grado di modificare il loro stato. È possibile applicare questa politica in modi diversi, oltre a trasformare i componenti in classi complete con interfacce e campi separati pubblici e privati.

Molte persone non parlano di questo aspetto di ECS, ma il più grande vantaggio di ECS per me personalmente era in realtà la semplificazione del mio sistema. È molto più facile ragionare su un motore con 20 sistemi, anche se dietro di essi hanno implementazioni piuttosto complesse, rispetto a un sistema con un centinaio di tipi di oggetti più piccoli con funzioni all'interno di essi che interagiscono tra loro, anche se tali funzioni sono più semplici. Se si tracciano le dipendenze in un ECS, è ridicolmente semplice con solo frecce che puntano dai sistemi ai componenti, non i componenti ad altri componenti e componenti ai sistemi. Perderai molti vantaggi se i tuoi sistemi non sono gli unici con la funzionalità.

2.) I don´t use a system for every type of component.

Questa è una tendenza naturale se si è tentati di fornire funzionalità nei componenti. Ora stanno mescolando le responsabilità dei sistemi in una certa misura. Nel tuo ECS normale, i sistemi sono gli unici che forniscono funzioni e per motivi che puoi apprezzare se finisci seguendo lo stesso percorso che ho descritto sopra.

3.) Entities can have more than 1 component of the same type [...]

Ancora una volta ho avuto una tentazione simile. Tuttavia, ciò lo rende così non è più possibile esprimere efficacemente le proprie operazioni in modo chiaro in base al tipo di componente. Non posso più dire, "Dammi tutte le entità nel sistema che hanno una componente ossea e di movimento". Per lo meno dovrei cambiare la mentalità più per piacere, "* Dai me tutte le entità nel sistema che hanno almeno un componente osseo e di movimento . *

Anche se questo potrebbe non sembrare un grosso problema, moltiplica la complessità in un modo in cui devi separare l'idea di un'istanza del componente osseo dal tipo di componente osseo in termini di operazioni legate all'entità. Tutti i sistemi devono quindi lavorare con l'ipotesi che possa esistere un numero variabile di componenti di ogni singolo tipo di componente possibile, allegato a una data entità. Ho trovato questa complessità più problematica di quanto valga la pena perché la complessità del design si diffonde in ogni angolo di ogni sistema con infinite domande che vengono sollevate come, "Cosa dovrebbe fare un sistema fisico con entità che hanno 2 o più componenti di movimento? ". Anche se riesci a trovare una risposta semplice a queste domande, il fatto che un tale progetto sollevi così tante domande (sia dell'utente che tecnico) con ogni singolo sistema è un segnale per me che è una lattina di vermi.

Invece puoi effettivamente creare tipi di componenti specifici in aggregati, come un componente skeleton che consiste di una o più ossa invece di un componente bone . Invece di generalizzare il tuo sistema per consentire il numero di istanze di componenti dello stesso tipo da collegare a una singola entità, puoi avere tipi di componenti che sono gli aggregati stessi.

Ad ogni modo, potresti essere in grado di trovare qualcosa di carino per i tuoi scopi deviando in questo modo, ma sappi che questi schemi non si sono presentati in modo arbitrario. Le persone hanno probabilmente esplorato le stesse idee alternative che hai avuto solo per accontentarsi dell'approccio ECS poiché è ampiamente applicato ora, e anche se ho avuto un momento difficile apprezzandolo all'inizio e ho avuto tentazioni simili a te, io ora, in senno poi, non farei le cose in nessun altro modo.

    
risposta data 29.11.2017 - 10:27
fonte
-2

[Is it] a good idea to experiment with given patterns and try to do things your own way?

I pattern esistono per due motivi: (1) ti fanno risolvere un problema specifico , (2) in un modo che rende facile per gli altri capire cosa sta succedendo nel tuo codice . Modificando un modello esistente, vai contro quelle ragioni originali.

Facciamo un esempio. Devo essere in grado di eseguire un pezzo di codice se una condizione è vera, o un altro pezzo di codice se la stessa condizione è falsa, a meno che non sia in un caso specifico, nel qual caso voglio che venga eseguito il terzo pezzo di codice . Questi pezzi di codice eseguono cose diverse, ma la loro interfaccia è identica.

Posso usare uno schema di strategia per questo. Posso raggruppare tre classi con i pezzi di codice e posso denominarli *Strategy . La prossima volta che un'altra persona sta leggendo il mio codice, capisce immediatamente che sto usando un modello di strategia.

Ora, immagina che quei pezzi di codice non abbiano interfacce identiche. Posso:

  1. Evita di usare qualsiasi cosa che assomigli al modello di strategia.

  2. Rendi il codice simile al modello di strategia, ma scegli un nome diverso.

  3. Rendi il codice simile usando lo schema di strategia e usa ancora il suffisso *Strategy .

L'ultimo caso è il peggiore. Rende il mio codice soggetto a errori e particolarmente poco chiaro. Non farlo mai. Il secondo caso è leggermente migliore, ma può ancora indurre un lettore a credere che sia un modello di strategia. Una corretta convenzione di denominazione potrebbe aiutare a prevenire questo tipo di errori. Il primo caso è ancora il migliore; il lettore sa che questo è un codice personalizzato e non prevede di trovare alcun modello specifico.

Quindi, se modifichi uno schema:

  • Non usare mai il nome del modello originale.

  • Assicurati che non assomigli al modello originale, ovvero che le tue modifiche siano notevoli.

Especially I care about this because want to use this approach in my graduation work

Se il tuo insegnante si aspetta che tu usi i modelli esistenti, modificarli darebbe solo un'impressione che non capisci o non hai imparato i modelli in primo luogo. Quindi, anche qui, è meglio evitare di cambiare i pattern.

    
risposta data 16.10.2017 - 21:53
fonte

Leggi altre domande sui tag