2010-10-25 8 views
8

Nella mia app ho un Controller avviato con il metodo principale. Il controller inizializza gli hook, le connessioni al database, l'interfaccia utente, un'altra connessione e altre cose. Detiene la maggior parte dello stato del programma (no, non è un Singleton). In un altro esempio c'è un controller per il bot che gestisce l'interpretazione e l'invio di comandi. Entrambi sono file piuttosto grandi.Come posso scrivere un controller senza renderlo un oggetto God?

Ho letto su oggetti di Dio, ma non so davvero come dividerlo. Se divido l'interprete e il dispatcher nel bot, farò una catena di chiamate orribile (qualcosa come getBot().getParser().getOutput().sendMessage(recipient, message)). Allo stesso modo nel primo Controller, se divido le cose, avresti solo oggetti Data che contengono campi e alcuni metodi di utilità alias. Dividerli non farebbe altro che peggiorare le cose. E prima che tu pensi che sia irrinunciabile, in realtà non lo è. Non ho nemmeno scritto il controller Bot, ma so ancora cosa sta succedendo.

Il problema è che la classe Bot è lunga 2000 righe (probabilmente più breve se ho estratto i commenti Javadoc) e il Bot è lungo circa 1000 righe. Molte linee = Dio oggetto. Ma va bene per una o due classi principali di un progetto?

+0

Correlati: [Progettare una classe in modo che non diventi un "oggetto di Dio"] (http://stackoverflow.com/questions/2589703/designing-a-class-in-such-a- way-it-it-doesnt-become-a-god-object) –

+0

@jleedev L'ho visto, ma questo è un altro problema. L'OP in cui possono essere creati oggetti secondari funziona correttamente poiché è tutto interno. Tuttavia, il mio caso è un controller API pubblico che deve rimanere semplice dove non riesco a far fare il lavoro a nessun altro oggetto. – TheLQ

risposta

11

"Un sacco di righe" non significa che la classe sia un oggetto divino, è un terribile punto di riferimento terribile per capire se è necessario o meno un refactoring. Alcune cose sono molto complicate e garantiscono un oggetto complicato e intrinsecamente grande. L'idea di un oggetto di Dio è ciò che la classe compie.

Per esempio se un oggetto fatto che potrebbe

DoMyTaxes() 
GiveMeHugs() 
LogThisError() 
StartGameLoop() 

L'oggetto sarebbe qualificarsi come oggetto dio, anche se può essere solo 100 righe di codice. L'idea di base è che tutto quanto sopra è del tutto estraneo (nella logica di business alla fine dello spettro), quindi perché nel mondo sarebbero tutti parte dello stesso oggetto. Se decidessi di far durare gli abbracci, potrei finire per rovinare le mie tasse. Inserisci l'IRS.

Tuttavia, se si sta lavorando su un simulatore di fisica, permette di dire, e la classe Classical() avrebbe metodi/oggetti quali:

Space() 
Time() 
Velocity() 
Speed() 
Mass() 
Acceleration() 
Gravity() 
Force() 
Impulse() 
Torque() 
Momentum() 
AngularMomentum() 
Inertia() 
MomentOfInertia() 
ReferenceFrame() 
Energy() 
KineticEnergy() 
PotentialEnergy() 
MechanicalWork() 
VirtualWork() 
DAlembertsPrinciple() 

(per gentile concessione di Wikipedia)

Questo oggetto non sarebbe essere un dio oggetto.È un oggetto complesso. Tutto ciò che riguarda la fisica newtoniana passa attraverso di essa, ma non è un oggetto di Dio .. è solo un oggetto davvero molto grande. Quanto sopra potrebbe finire per essere migliaia di righe di codice.

L'oggetto Quantum() sarebbe ancora più complesso, inutile dirlo.

Per ribadire, l'idea è di circa il comportamento di un programma di, non flusso di dati:

non ti importa se un singolo oggetto contiene un sacco di dati del app, o se la maggior parte dei flussi deve passare attraverso un singolo oggetto. Ciò che ha più impatto sulla manutenibilità è quando una singola classe God (tm) ha un comportamento eccessivo (codice aziendale).

Se si pensa ci sia un problema, si potrebbe tentare di implementare diverse forme di mediation, o modelli più brutte, come dependency injection.

+0

Buona risposta. Seguendo questo principio immagino che il mio oggetto sia solo complesso poiché gestisce sia l'analisi, l'output, sia i ganci (anche se gli hook si stanno spostando). Grazie per la risposta – TheLQ

+0

risposta davvero buona, +1 –

3

Se si è a disagio con le dimensioni e la complessità di un corso, di solito è un buon indicatore che si potrebbe fare un progetto migliore. Ma non misurare solo sulla taglia. Se una classe è facile da capire e da seguire, ma contiene molto codice, questo non significa necessariamente che sia un candidato per il ri-factoring. Ho visto persone prendere il largo con questo e il disastro che creavano nel cercare di rendere le cose piccole era peggio del codice originale. D'altra parte, ho letto le lezioni da capo a fondo più volte e non avevo ancora idea di cosa facessero.

La domanda che vorrei porre è - Se ho dato questo a un altro sviluppatore, sarebbero in grado di capire facilmente e mantenerlo?

Se la risposta è sì, allora le probabilità sono che non è necessario fare nulla. In caso contrario, è necessario un ri-factoring.

Con riferimento agli oggetti di dio, leggendo il tuo post, sembra che questa classe stia facendo troppo. Mi chiedo se in primo luogo si possa ridimensionare lo stato in un insieme di oggetti modello come punto di partenza. Quindi la tua classe inizia ad assomigliare più ad una fabbrica di configurazioni di qualche tipo.

2

Suggerirei che il motore di fisica/movimento debba essere assolutamente separato dall'interprete di lingua; sebbene l'interprete linguistico abbia bisogno di accedere ad alcuni metodi e proprietà pubbliche del motore fisico, non c'è ragione per cui i due aspetti del robot debbano essere nella stessa classe. L'interprete del linguaggio stesso potrebbe essere suddiviso in poche classi, come dovrebbe essere il motore di movimento. Potrebbe esserci un oggetto di controllo principale, ma dovrebbe avere una quantità relativamente piccola di codice. Esso, il motore di movimento principale e il motore di linguaggio principale, dovrebbero delegare la maggior parte del loro lavoro agli oggetti che li compongono.

0

Penso che il principio chiave qui sia "coesione".

DoMyTaxes() 
GiveMeHugs() 
LogThisError() 
StartGameLoop() 

..non è coeso.

Qualcosa di simile:

GiveMeHug() 
GiveMeKisses() 
GiveMeHugs(int noOfTimes) 
GiveMeHugs(int noOfTimes, Person person) 
GiveMeHugsAndKisses() 

..è coesa dal momento che tutti i metodi sono abbastanza simili. Potresti avere 1000 metodi coesivi in ​​una classe e non sarebbe ancora un oggetto divino, dal momento che la responsabilità della classe è ancora limitata.

Problemi correlati