Sto facendo un gioco Ho un oggetto Replay
che rappresenta tutti gli input fatti da un giocatore per finire un livello. Sembra che:
class Replay {
int replayId;
int playerId;
int levelId;
int length;
List<Input> inputs;
}
Voglio essere in grado di cercare e accedere ai replay molto velocemente, quindi li sto salvando in un database. Tuttavia, mi è stato detto non dovrei usare il database per archiviare file binari di grandi dimensioni. Quindi sto memorizzando il replayId
(chiave primaria), il playerId
, il levelId
e il length
sul database e l'oggetto completo è serializzato in un file chiamato usando la chiave primaria. Tutto ciò va bene e posso avvolgere completamente quelle cose hacky in un oggetto che astrarrà il caricamento e il salvataggio di oggetti Replay
.
Tuttavia, progettando quell'oggetto, verrò per caso in cui non ho bisogno di caricare completamente Replay
, ma ho semplicemente bisogno dell'id del giocatore che l'ha fatto o dell'ora. Quindi ho finito per creare metodi che assomigliano un po 'a questo:
interface ReplayService {
//query to Database and then loading from disk
Replay getWorldRecord(int levelId) throws LevelNotFoundException, RecordNotSetException;
//query from database only and return length
int getWorldRecordTime(int levelId) throws LevelNotFoundException, RecordNotSetException;
//query from database only and return playerId
int getWorldRecordHolder(int levelId) throws LevelNotFoundException, RecordNotSetException;
}
Questa è la soluzione più pulita che ho trovato, ma il problema è che il tempo e il titolare del record vengono trovati insieme a una singola query SQL. Ciò rende l'implementazione molto stupida per i 2 metodi che restituiscono un singolo valore della stessa query. Quando un utente che dovrà visualizzare l'ora e il titolare, pagherà il prezzo di 2 query anziché 1 che restituisce comunque tutti i dati dal database. Quindi avrei bisogno di un modo per raggruppare quei 2 (o più) campi che voglio recuperare contemporaneamente.
interface ReplayService {
//query to Database and then loading from disk
Replay getWorldRecord(int levelId) throws LevelNotFoundException, RecordNotSetException;
//query from database only and return all infos without the data
SomeKindOfType getWorldRecordInfo(int levelId) throws LevelNotFoundException, RecordNotSetException;
}
Ho cercato Pair
oggetti in Java e ho incontrato persone che spiegavano perché è cattiva pratica e qualsiasi oggetto dovrebbe avere un nome significativo. Sono d'accordo con questo come anche se non voglio pagare per 2 query, ma non voglio nemmeno offuscare il mio codice.
Anch'io odio davvero Info
oggetti come ReplayInfo
poiché un oggetto Replay
valido dovrebbe contenere le sue informazioni e la parola Info
non aggiunge nulla in termini di significato. È un po 'lo stesso per Metadata
. Ma non sono sicuro di avere altre opzioni migliori. Devo creare un nuovo tipo per memorizzare la parte Database dell'oggetto? Spero di no dato che la cosa di Database / File hacking è parte dell'implementazione e non del design. Mi piacerebbe essere in grado di realizzare un'implementazione diversa che memorizza i dati in modo completamente diverso senza che l'API si senta a disagio.
Qualche idea su come progettare un sistema utilizzando oggetti incompleti per motivi tecnici, ma vuoi comunque rimanere pulito e facile da capire? Devo solo schivare l'oggetto Info
/ Metadata
con un generico Pair
o Tuple
?