2015-05-04 9 views
5

Attualmente sto lavorando al mio primo progetto java più grande (un gioco) e sto avendo già un po 'di problemi di organizzazione con solo poche (~ 40) classi .
che sto organizzando il mio gioco qualcosa di simile:Java: il modo migliore per accedere ai metodi da oggetti lontani

Project Organisation Model

che sembra abbastanza organizzata per me come ogni classe più piccola è classificato in una classe più ampia. Ovviamente classi come la ObjectHandler o la Model conterranno più classi, altrimenti sarebbero inutili.

Ora il mio problema è: quando sto cercando di accedere al corrente PlayerSettings dal DynamicObjects nel GUI (per esempio quando sto cercando di ottenere la posizione del giocatore al fine di trarre sulla tela), avrei dovuto creare un lungo percorso come questo: (. a tal fine ho impostato maggior parte dei parametri public potrei anche renderle accessibili con get() -metodi, ma che sembra ancora più disorganizzata a me)

int x = gui.engine.model.objHandler.player.playerSettings.getX(); 

La mia domanda è - sembra un po? ormal o ci sono modi migliori per risolvere questo problema organizzativo?

+0

No, non è così che si dovrebbero accoppiare le proprie dipendenze. Come regola generale, "ogni unità dovrebbe parlare solo con i propri amici, non parlare con estranei". Vedi anche: [Law of Demeter] (http://en.wikipedia.org/wiki/Law_of_Demeter). –

+0

È generalmente contro le regole della programmazione accedere a tutto pubblicamente in questo modo ....:/ma l'ho fatto in passato quando stavo solo imparando a mantenere le cose semplici. Funziona .... ma – TheJavaCoder16

+0

Direi che per qualsiasi applicazione che desideri codificare, l'utilizzo di buone pratiche e modelli di progettazione è sempre il meglio che puoi fare. Per il caso dei giochi, perché non provi questo link? Mi è stato utile quando ho creato un gioco di ruolo qualche tempo fa: http://gameprogrammingpatterns.com/contents.html –

risposta

0

Un modo rapido per eliminare i problemi di dipendenza come questo è utilizzare EventBus di Google Guava. Puoi usarlo per pubblicare eventi e quindi qualsiasi cosa sottoscrivere questi eventi agirà su di loro, senza che nessun componente si conosca o da dove gli eventi provengano. È un modo rapido per disaccoppiare in modo efficace e gestire le dipendenze in modo efficiente.

Se vuoi qualcosa di ancora più elegante, guarda la programmazione reattiva ed esplora RxJava.

2

La risposta breve è che - no, non vorrai una situazione in cui devi de-referenziare sei oggetti per ottenere i dati di cui hai bisogno.

Questo probabilmente significa che c'è qualcosa di sbagliato nel modo in cui si interrompono i dati e le funzionalità in classi. In genere si desidera raggruppare oggetti che devono comunicare tra loro.

Un consiglio pratico è che i tuoi oggetti non devono formare un albero. Potrebbe avere senso che DynamicObjects tenga un riferimento a PlayerSettings. Questo è solo un esempio: non so cosa abbia senso nella tua applicazione, sto solo cercando di far notare che non devi pensare alle relazioni oggettuali come ad un albero.

E per quanto riguarda i metodi get contro i membri pubblici: è una convenzione Java che utilizza variabili private con getter e setter. Ha a che fare con la manutenibilità e la modifica dell'implementazione nella funzione. Anche se questo non ti convince, penso che sia una buona cosa acquisire gli standard di stile che sono comuni nella codifica Java.

+0

Il problema è che la maggior parte degli oggetti sono legati a tre percorsi di albero completamente diversi. Il lettore viene modificato dal controller (input dell'utente), viene letto dalla GUI e può anche essere manipolato dall'orologio. Lanciare tutti gli oggetti casualmente insieme e creare percorsi confusi tra molte classi mi sembra ancora più disordinato. –

2

Come suggerisce il Law of Demeter, avendo le dipendenze loosely coupled e come ignoranti di altre classi il più possibile, contribuisce a rendere l'applicazione più gestibile. La riduzione dell'accoppiamento tra i componenti consente di ridefinire rapidamente o modificare singoli moduli/classi.

La GUI non dovrebbe sapere da dove proviene l'oggetto impostazioni giocatore, né dovrebbe esserci un motivo per cui la GUI recupera le informazioni stesse; l'oggetto dovrebbe invece essere iniettato nella GUI..Esistono molti framework che abilitano Dependency injection per te, come Google Guice, ma puoi anche implementare una versione semplicistica semplicemente fornendo l'oggetto come parametro alla GUI, nel costruttore o in uno specifico metodo di inizializzazione.

public class MyGUI { 
    private PlayerSettings settings; 
    //...  
    public void initialize(PlayerSettings settings) { 
     this.settings = settings; 
    } 
    //... 
} 

Inoltre, cercare di organizzare il codice in pacchetti significativi e ridurre la visibilità delle classi di un pacchetto in modo che essi non sono accessibili da "lontano". Esporre solo un'API pubblica all'esterno del pacchetto affinché altri possano utilizzarla e vederla. Lo stesso vale per i metodi e i campi all'interno delle classi; non si dovrebbero usare i campi public (a parte le costanti). Esporre il meno possibile le informazioni al di fuori e sarà possibile refactoring il codice all'interno della classe (o pacchetto) senza rompere il codice che è "lontano".

+0

Ma questo significherebbe che dovrei passare dozzine di oggetti dalla categoria "Modello" alla categoria "GUI" quando il mio gioco cresce. E anche in quel caso dovrei gestirlo con il 'Engine' che prima deve passare attraverso i percorsi per trovare classi come' PlayerSettings' e poi inviarlo alla 'GUI'. Nel tuo caso di esempio è facile passare un oggetto PlayerSettings a MyGUI, ma se ho bisogno di molti più oggetti da pacchetti diversi sarà un sacco di passaggi e di inizializzazione. –

+0

Questo probabilmente significa che la classe 'GUI' ha troppe responsabilità - dividerla in moduli/classi che hanno compiti ben definiti. Sto solo indicando alcuni principi generali qui - potresti voler fare un'altra domanda su come organizzare al meglio l'interazione tra 'Model',' GUI' e 'Engine'. Forse hai già familiarità con [Model-view-controller] (http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) o concetti di progettazione della GUI correlati? –

+0

Sì, ho familiarità con il concetto MVC. Ecco perché il mio codice sembra così strutturato, perché stavo cercando male di fare tutto con MVC.Suddividendola in moduli intendi avere sottoclassi nella GUI (come faccio con 'Background',' DynamicObjects' ecc.) O dando queste sottoclassi al 'Motore'? –

Problemi correlati