Come posso strutturare il mio codice quando ho array ortogonali di funzionalità?

3

Esempio:

Hai un gioco con diverse scuole di magia (fuoco, ghiaccio, ecc.). Ogni scuola ha una serie di proprietà relative a caratteristiche indipendenti del gioco, come ad esempio:

  • stringhe da visualizzare sulla GUI (dati generici archiviati in memoria)
  • grafica, suoni e altri file da caricare se necessario
  • comportamenti diversi (codice), ad es. ogni scuola di magia ha una diversa interazione con vari tipi di terreno

Posso pensare a due design per l'implementazione di questo, ma non mi piace particolarmente nessuno dei due.

  1. Potrei creare una classe astratta MagicSchool che contenga tutte le varie proprietà di una determinata scuola. Questo rende la classe MagicSchool dipendente da molte caratteristiche distinte del gioco (GUI, SFX, altre aree di logica di gioco, ecc.), Che sembra una inutile mescolanza di preoccupazioni (qualcosa di una classe di Dio).
  2. Potrei inserire i dati GUI / SFX / etc per ogni scuola nei sistemi GUI / SFX / etc come array. Ma poi il codice per le scuole magiche viene sparpagliato in tutto il progetto (anche se in posti molto logici).

Quindi in questo caso ci sono due assi lungo i quali strutturare il codice: le varie scuole di magia e le varie funzionalità in cui sono presenti le scuole.

In termini di chiarezza e manutenibilità, quale delle due soluzioni di cui sopra dovrei preferire? O forse c'è un altro modo che non ho ancora considerato?

    
posta suszterpatt 12.12.2013 - 01:22
fonte

1 risposta

1

Non sono sicuro di comprendere appieno il problema, diciamo cosa succede se lo facciamo in questo modo (in un linguaggio simile a Java):

Definisci interface per i tuoi tre proiettili, ad esempio GUI , FX e Behavior . Ad esempio:

interface GUI {
    String name();
    ....
}

interface FX {
    Image image();
    Sound sound();
    ....
}

interface Behavior {
    Interaction interact(Terrain t);
    ....
}

Ogni abstract MagicSchool è un prodotto di oggetti estratti da ciascuna dell'interfaccia precedente:

abstract class MagicSchool(GUI gui, FX fx, Behavior b) {
    GUI gui();
    FX fx();
    Behavior behavior();
}

Per visualizzare l'elemento della GUI di una scuola, possiamo fare qualcosa come:

System.display(school.gui().name());

Ora, ad esempio, vuoi definire Fire :

class FireGUI implements GUI { .... }
class FireFX implements FX { .... }
class FireBehavior implements Behavior { .... }

Ora definisci FireSchool come prodotto di questi, sovraccaricando il costruttore:

class FireSchool = MagicSchool {
    FireSchool() {
        super(new FireGUI(), new FireFX(), new FireBehavior());
    }
}

O se non hai realmente bisogno di una nuova classe, basta definire scuole e comportamenti ad-hoc:

iceSchool = new MagicSchool(new GUI() { /* Ice GUI */ },
                            new FX() { /* Ice FX */ },
                            new Behavior() { /* Ice behavior */ });

Java non ha un modo conveniente per eseguire funzioni di ordine superiore, quindi promuovo GUI , FX , Behavior al livello di interface per ridurre il carico sintattico in alcuni punti. Se la tua lingua ha funzioni di prima classe, definisci tutti quelli come oggetti.

    
risposta data 12.12.2013 - 03:11
fonte

Leggi altre domande sui tag