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?