Java ha bisogno di chiamare molti metodi in modo sistematico

1

Ho un gruppo di metodi che sarà molto grande. Devo essere in grado di chiamare sistematicamente i metodi da un grande gruppo, in due modi diversi. I metodi creano un nuovo oggetto oggetto con variabili specifiche per il tipo di oggetto creato, ad esempio gomma (); il metodo crea un oggetto con

itemId = 12, weight = 1, name = "Rubber", ...

per oltre 20 variabili. Attualmente sono in grado di chiamarli per nome

object.rubber();

Voglio poterle chiamare per itemId

object.getById(12);

Devo essere in grado di elaborarli per itemId per situazioni come questa:

/* itemId:
1: ruined copper
2: weak copper
3: refined copper
4: ruined iron
5: weak iron
6: refined iron
7: ruined brass
-(More metals in this pattern)-
36: sturdy aluminum
*/


//within furnace class

public void smelt(item input, inventory furnace){
//input is the item to smelt, furnace is the furnace's crucible.

    if(input.getId() < 36 && input.getId()%3 = 1){
    //if the imput's ID is less than 36, it's a metal, and if ID % 3 = 1, it's a ruined metal, meaning it is smeltable.

        furnace.addItem(handler.list.addById(input.getId() + 1))
        //add an item to the furnace with an ID one higher than that of the input, which will be a 'weak' metal of the same type

        furnace.removeItem(input);
        //delete the input item
    }
}

I metalli sono tutti ordinati regolarmente, quindi se posso chiamarli per ID sarà possibile manipolarli con un codice molto piccolo, mentre altrimenti il forno avrà bisogno di un'istruzione if per ogni singolo metallo per determinare in che cosa si fonde. Molti altri processi dovranno essere in grado di funzionare in modo simile.

Ho trovato finora due soluzioni possibili:

uno sarebbe usare reflect per chiamare i metodi, ma sono stato avvertito che è notoriamente instabile e difficile da capire.

l'altro sarebbe quello di revisionare il mio attuale sistema e memorizzare le proprietà dell'oggetto su un file di testo, qualcosa del tipo

Ruined_Copper false 4 256 ...
Weak_Copper false 4 128 ...
etc.

e quindi fare in modo che una persona che ha aperto il file apra il file e contenga le linee finché il numero di riga non ha eguagliato il valore itemId di destinazione. Dividerebbe quindi la linea per spazio e assegnerebbe i valori alle variabili, cioè:

newItem.setName(lineOutput(1));
newItem.setIsContainer(lineOutput(2));
...

Ciò produrrebbe un elemento con

name=Ruined_Copper, isContainer = false, etc.

Preferirei scoprirlo all'inizio dello sviluppo, quindi non dovrò modificare migliaia di elementi in un nuovo formato in futuro. Quale di questi andrà più veloce? Quale sarà più stabile? C'è un modo migliore tutto insieme?

EDIT: Per chiarire, mi rendo conto che sarebbe una cattiva idea avere metalli 0-36, legni 37-56, ecc. Il mio obiettivo è permettere che gli oggetti sistematici o creati dai giocatori vengano aggiunti dalle azioni del giocatore in gioco , quindi il prodotto finito avrà spazio tra le categorie, cioè 0-60 sono metalli, 61-999 sono vuoti, 1000-1085 sono tipi di legno, 1086-1999 sono vuoti, ecc.

    
posta krill 23.01.2016 - 23:48
fonte

3 risposte

5

Quando si sviluppano giochi è spesso una buona idea separare il motore di gioco dal contenuto del gioco spostando tali informazioni in file esterni. Permette di armeggiare con i valori senza dover ricompilare il gioco, consente ai non programmatori di modificare questi file e rende il gioco più modding-friendly.

Tuttavia, tieni presente che l'accesso ai file è molto lento rispetto all'accesso alla memoria. Pertanto, è necessario analizzare tali file una volta all'avvio e memorizzare le informazioni in memoria.

Se vuoi cercare oggetti per numero, puoi usare ArrayList<ItemType> . Se vuoi cercare oggetti per nome, puoi usare HashMap<String, ItemType> .

L'uso di numeri ID con determinati intervalli "magici" ti morderà prima o poi. Quando gli oggetti 0-36 sono in metallo, cosa farai se un giorno deciderai di aggiungere ancora più tipi di metalli al gioco? Dovresti estendere tale intervallo in un intervallo che potrebbe già essere preso da articoli non metallici, che devono quindi essere rinumerati. Questo può diventare abbastanza brutto, ad esempio con la retrocompatibilità dei salvataggi. O se decidessi che ti piacerebbe avere metalli con più o meno di tre livelli di qualità?

Un design migliore sarebbe se il numero ID dell'oggetto stesso non contenga informazioni inerenti e che le informazioni vengano lette anche dal file di configurazione:

name="Ruined Copper", weight=1, category="metal", qualityLevel=0, smeltsTo="Weak Copper"
name="Weak Copper", weight=2, category="metal", qualityLevel=1
    
risposta data 24.01.2016 - 01:25
fonte
4
if(input.getId() < 36 && input.getId()%3 = 1){
//if the imput's ID is less than 36, it's a metal, and if ID % 3 = 1, it's a ruined metal, meaning it is smeltable.

Dare un significato magico ai numeri di identificazione è un problema. Cosa succede se vuoi aggiungere un nuovo tipo di metallo? Che ne dici di rimuoverne uno? Che ne pensi di aggiungere un nuovo stato? Moltiplicalo su tutti i diversi tipi di oggetti nel tuo gioco e hai un disastro incombente.

one would be to use reflect to call the methods, but I've been warned that it's notoriously unstable and difficult to figure out.

Di solito unstable significa qualcosa che si blocca molto o qualcosa che cambia molto. Nessuno di questi è vero di riflessione. Anche non è davvero difficile. Tuttavia, la riflessione è lenta, impedisce al compilatore di controllare il codice tanto, rende inefficaci gli strumenti di refactoring e generalmente indica un design scadente.

the other would be to overhaul my current system and store the item properties on a text file

Sono un grande fan della configurazione. Quando è possibile, mi piace mettere i dettagli nella configurazione piuttosto che nel codice. Questo riduce la duplicazione e il boilerplate. Segue la regola del minimo potere. Ci sono diversi modi per farlo:

Un modo è un file di testo come dici tu. Non consiglierei un file di testo normale, userei YAML o JSON come sintassi di base. Che hai l'analisi gratuita e vari strumenti per aiutarti a lavorare con esso.

Un altro modo è java enums. Le enumerazioni Java sono oggetti e puoi allegare a loro dati e metodi aggiuntivi. Mi sono un po 'stancato delle enumerazioni perché è tentato di accenderle quando dovresti aggiungere una proprietà, e non posso creare enumerazioni in fase di runtime. (È utile essere in grado di costruire combinazioni arbitrarie di proprietà nei test)

Un altro modo è semplice creare oggetti immutabili in java. Con l'approccio del file di testo, alla fine si creano oggetti java dai dati. Potresti anche creare direttamente gli oggetti java. Questo è un po 'carino perché non devi uscire da java per modificare i tuoi oggetti. D'altra parte, è più difficile sviluppare / utilizzare strumenti che manipolino i dati.

    
risposta data 24.01.2016 - 01:37
fonte
0

La mia soluzione è un file di configurazione in cui hai una proprietà associata al metodo in configurazione. Questo sarà usato in una classe di builder.

E hai anche una configurazione in cui fornisci le proprietà in xml / properties / json.

es

Configurazione generatore name = setName () category = setCategory qualityLevel = setQualityLevel

Valore Config name = Jack category = metallo qualityLevel = 1

Codice Pseduo   Leggi BuilderCOnfig e store.

While (Value Config.hasElements ()) {    method = BuilderConfig.getMethod ()    chiama object.method (); }

Questo rende tutto configurabile per aggiunte future a proprietà / metodi. Fa anche attenzione quando mancano alcune proprietà.

L'elemento builder può essere usato se usi Spring, il quale automaticamente collega i metodi se sono denominati in modo coerente. E tutto ciò di cui hai bisogno è un mucchio di file xml.

    
risposta data 24.01.2016 - 03:31
fonte

Leggi altre domande sui tag