Sto lavorando a un gioco in rete. Ho provato a progettare i vari componenti (client, server, engine) solo su cose all'interno del loro dominio. Ad esempio, il server dovrebbe occuparsi solo della gestione dei pacchetti e delle connessioni, non delle entità all'interno del motore di gioco o della gestione degli eventi hardware sul lato client. Non sono stato in grado di trovare un buon modo per unire insieme questi domini in modo pulito, perché alla fine, un'entità che si muove nel mondo del gioco alla fine deve essere rappresentata all'utente in qualche modo. Questa è una domanda correlata, ma forse non è il nucleo di questa.
Con questo in mente, ho osservato alcune delle mie classi e mi sono chiesto se fossero progettate in modo pulito.
Un esempio che ho è una classe Party
, che rappresenta un gruppo di Pokemon (animali con cui combattere). Il mio progetto iniziale assomigliava a
// Max number of Pokemon is 6.
public interface Party {
Set<Pokemon> getPokemon();
void add(Pokemon pokemon);
void remove(Pokemon pokemon);
boolean contains(Pokemon pokemon);
boolean contains(Species species);
int getNumberOfPokemon();
}
La maggior parte dei metodi nell'interfaccia espongono lo stato di Party
. Ci si aspettava che il codice client verificasse se il numero di Pokemon all'interno del party fosse inferiore a 6, e in tal caso, era permesso a add
per il party; oltre a verificare che ci fossero almeno 2 nella parte prima che venisse chiamato remove
. L'ho semplificato un po 'nel tentativo di esporre meno dello stato dell'oggetto, e mi è rimasto con
public interface Party {
boolean hasRoom();
void add(Pokemon pokemon);
void remove(Pokemon pokemon);
}
Un Party
viene utilizzato in molti posti tra i domini del codice. Ad esempio, c'è una vista sul lato client che mostra all'utente ciò che è nella loro Party
. È anche memorizzato in un repository.
La classe% co_de dovrebbe sapere come inviarsi al client e al repository?
public interface Party {
// ...
void saveTo(PartyRepository repo);
void showUITo(Client client);
}
Certo, farlo in questo modo mantiene lo stato della festa bloccato all'interno dell'oggetto, ma poi corri il rischio di avere molti oggetti quasi-dio, che sanno tutto di come vengono utilizzati.
Un'alternativa che avevo pensato era quella di dividere Party
in due tipi distinti, uno specificamente progettato per rappresentare lo stato e uno per rappresentare il comportamento. Ma vedere come Party
è solo una collezione di Pokemon, sarebbe davvero qualcosa di simile a
public interface PartyDTO {
Set<Pokemon> getMembers();
}
public interface PartyBehavior {
void add(Pokemon pokemon);
}
Che comunque non sembra giusto perché allora quale è il Party
? Continuerò a manipolare lo stato della classe Party
attraverso la classe PartyDTO
, quindi non mi sembra di guadagnare davvero qualcosa.
È qualcosa che dovrebbe essere fatto? Quali alternative ci sono?