2010-01-23 9 views
5

Diciamo che esiste una classe chiamata Explosion in cui non ha senso creare un'istanza di esso, senza alcune informazioni da un'altra istanza di classe. Il costruttore non è reso pubblico.Creazione di un oggetto in base allo stato di un altro oggetto in Java

è meglio fare in questo modo:

// both classes are in the same package 
Explosion e; 
Collision c = new Collision()  
// do some stuff with collision 
e = c.createExplosion() 

o è meglio per esplosione di avere un metodo statico per la creazione di un'istanza e si passa in un oggetto di collisione come argomento:

Explosion e 
Collision c = new Collision()  
// do some stuff with collision 
e = Explosion.createExplosion(c) 

Quando sei l'autore di entrambe le classi.

+0

Finisco con le soluzioni che mi piacciono di più quando progetto per un facile collaudo unitario. I metodi statici e gli operatori "nuovi" indicano classi specifiche e rendono difficili le implementazioni simulate. – Christian

risposta

1

Preferisco certamente il secondo perché quello è OO.

4

Perché il costruttore non è pubblico? Mi sembra sensato che Explosion abbia un costruttore che prende come riferimento un riferimento Collision.

In questo modo si potrebbe avere:

Explosion e; 
Collision c = new Collision(); 
// do some stuff with collision 
e = new Explosion(c); 
3

io preferisco il secondo approccio, come meglio divide la responsabilità tra le classi. Per rispondere alla tua domanda, chiediti chi ha la responsabilità di creare un'esplosione e agire di conseguenza. Il tuo secondo approccio utilizza fondamentalmente un metodo factory per nascondere il costruttore, ma la responsabilità è ancora all'interno della classe Explosion, che è buona IMO.

Perché il costruttore non è pubblico? puoi renderlo visibile e quindi passare il Collision come parametro costruttore?

3

Dipende ... in gran parte dalla dipendenza.

Se si considera Explosion sempre un livello inferiore o un peer di Collision, scegliere la flessibilità e la facilità d'uso di un metodo di istanza (virtuale). Ciò mantiene il comportamento negli oggetti e riduce la necessità di getter (che tendono ad essere un segno di progettazione scadente). Ovviamente hai ancora una chiamata al costruttore Explosion, solo ora è all'interno di Collision.

Se, d'altra parte, Collision non deve dipendere da Explosion, rivolgersi direttamente a un costruttore. Questa non è la fine dei metodi virtuali. Se le cose si fanno più complicate si potrebbe modificare il codice chiamante per chiamare un metodo virtuale su qualche altro oggetto che crea una configurazione specifica di Explosion da un passato in Collision.

1

Dipende molto dall'ambito del tuo sistema. Se vuoi davvero "fare il pieno", questo dovrebbe essere gestito da una terza classe, che rappresenta "fisica" sull'interazione nel tuo sistema.

Ecco perché: In primo luogo, una collisione può avere molte conseguenze: esplosioni, danni, punteggio (si tratta di un gioco)? suono, ecc. Non vuoi sovraccaricarli tutti nella collisione.

D'altra parte, le esplosioni possono accadere per un sacco di ragioni diverse (ad esempio, armi), l'esplosione dovrebbe sapere esplicitamente tutto ciò che può causare?

Se stai modellando molte sfaccettature del "mondo", potresti voler avere un terzo sistema che è responsabile di queste cause-ed-effetti.Prende ciò di cui ha bisogno sullo stato di un oggetto e crea l'altro con lo stato necessario senza che debbano conoscersi l'un l'altro.

1
  • Effective Java (2nd chapter) consiglia di utilizzare un metodo di fabbrica statico, ovvero la seconda opzione.
  • seconda dei parametri da Collision che è necessario in esplosione, può essere meglio passare solo i parametri, quindi senza violare la Law of Demeter
1

Un vantaggio con il secondo approccio è che non è necessario creare l'oggetto esplosione ogni volta (facendo riferimento a Effective Java). Se si desidera avere un qualche tipo di meccanismo di memorizzazione nella cache (si supponga di voler restituire una stessa istanza di Explosion in base ad alcuni attributi della classe Collision), il secondo approccio è utile.

Il rovescio della medaglia, se la classe di esplosione fornisce solo un metodo di produzione statico per la creazione dell'istanza, non può essere sottoclassata.

Problemi correlati