Progettazione di un sistema OOP basato su XML facilmente estensibile

2

Ho lavorato a un progetto molto basato sui dati (un gioco da tavolo a scacchi con regole personalizzabili, sto utilizzando XML per l'archiviazione dei dati). Ho bisogno di un design che sia facile da estendere aggiungendo nuove funzionalità al progetto tramite nuovi tag XML.

Il mio schema XML si presenta come questo per una condizione di vittoria (correttori):

<game>
   <winconditions>
      <condition winner="Black">
         <Pieces color="Red" number="0" />
      </condition>
      <condition winner="Red">
         <Pieces color="Black" number="0" />
      </condition>
   </winconditions>
</game>

<game> è l'elemento radice. Ci sono altre sezioni principali come <board> che definisce la dimensione e la forma della tavola e il posizionamento dei pezzi, e <moves> che definisce come si muovono i pezzi. L'idea è di avere diverse "opzioni" che si combinano per formare una "condizione" - se tutte le "opzioni" sono vere, la valutazione della "condizione" restituisce un vincitore.

In questo momento, la strategia migliore che mi è venuta in mente è creare un pacchetto per le classi di elaborazione dei tag:

processors
   pieces

E un'interfaccia per un'opzione di condizione di vincita:

public interface WinConditionOption {
   void setParameters(HashMap<String, String> args);
   boolean evaluate(GameState state);
}

Il file processor, quando vede un tag all'interno del tag <winconditions> , usa reflection per cercare la classe corrispondente e la chiama usando l'interfaccia. Pertanto, il tag Pieces provoca la creazione di un oggetto Pieces e viene chiamato setAttributes() con gli attributi del tag. Quando controlliamo una vincita, viene chiamato evaluate() con lo stato attuale del gioco. Pieces valuterà se il numero di pezzi appartenenti a quel giocatore fosse un certo numero, 0 in questo caso (nessun pezzo rimasto).

È un buon design? C'è un modo migliore per farlo ed è ancora possibile scrivere un nuovo codice minimo per aggiungere una nuova opzione di vittoria?

    
posta Michael K 05.10.2011 - 19:38
fonte

3 risposte

1

Il design che hai indicato manca una caratteristica importante: la formattazione XML flessibile di nuove condizioni. In base al tuo post, questo non sarebbe possibile:

<condition ...>
    <pieceCombos>
        <combo>...</combo>
        <combo>...</combo>
    </pieceCombos>
</condition>

Un modo migliore sarebbe che ciascuna di queste classi sappia leggere (e scrivere) le proprie informazioni dall'elemento xml appropriato. Quindi qualcosa di simile potrebbe essere più pulito e più flessibile:

// This abstracts away specific methods of reading from xml.
public class YourXmlHandler
{
    ...
    GetChildElement(int index);
    GetAttribute(int index);
    ...
}

public interface IXmlReadable
{
    void LoadFromXml(YourXmlHandler reader);
}

public interface IWinOption
{
    bool Evaluate();
}

Ciò consente di riutilizzare l'interfaccia IXmlReadable per tutto ciò che è interessato dal contenuto XML. Lascia l'opzione di vittoria separata per gli elementi che devono essere vinti.

Si può finire con una classe WinConditions che sa leggere più voci di WinCondition dall'XML e una classe Pieces che sa come leggere i suoi dati. La classe WinCondition sa esattamente cosa vuole dall'XML e la ottiene o getta un'eccezione significativa.

    
risposta data 05.10.2011 - 22:55
fonte
1

Quasi ogni linguaggio comune ha una libreria standard per gestire questo genere di cose.

In Java c'è la libreria "Proprietà" che carica automaticamente un XML in una mappa hash. Altre lingue hanno librerie simili per gestire semplici file di configurazione XML.

Se il tuo file di configurazione è più di una semplice coppia di chiavi / valori, allora puoi usare Xereces di un parser XML completo e simile e usare Xquery per ottenere i dati richiesti.

Ma ricorda "la legge di Jim" - " Se hai un file di configurazione di Turing Complete, allora stai solo programmando in crappy langauge "

    
risposta data 06.10.2011 - 09:07
fonte
0

So the Pieces tag causes a Pieces object to be created and setAttributes() is called with the tag's attributes.

Questa è la serializzazione degli oggetti in XML. Stai de-serializzando un oggetto della classe data con i valori dati.

Non scrivere da solo. È una perdita di tempo. Basta scaricare uno che funzioni con la lingua di destinazione.

When we check for a win, evaluate() is called with the current state of the game.

destro. Hai deserializzato un oggetto. Ora valuti un metodo. Il metodo valuta quindi le varie clausole e condizioni per determinare e il valore complessivo.

Is there a better way to do it and still be able to write minimal new code to add a new win option?

Non proprio. Utilizza una serializzazione XML prontamente disponibile e puoi evitare di scrivere troppo codice.

    
risposta data 06.10.2011 - 00:00
fonte

Leggi altre domande sui tag