2015-04-26 9 views
5

Sto prendendo lezioni di disegno a scuola e ho letto alcuni capitoli di Head First Design Patterns. Quello che mi piacerebbe scoprire è fino a che punto i pattern di progettazione possono impedire la riscrittura del codice esistente.Fino a che punto è possibile impedire la modifica del codice esistente quando si utilizzano gli schemi di progettazione?

Prendiamo ad esempio le classi Duck e le classi FlyBehavior. Ho in public static void main(String[] args) il seguente codice:

Duck mallard = new MallardDuck(new FlyWithWings()); 

ho ragione nel dire che è inevitabile che si dovrà modificare il metodo di main() quando si desidera aggiungere una nuova strategia? In questo modo, è che modifica il codice esistente, giusto? Mi riferisco in particolare alla parte in cui si parla di una classe strategia concreta: new FlyWithWings().

Se implementato il metodo modello di fabbrica nel codice, si potrebbe evitare di dover una classe concreta (FlyWithWings) da essere menzionato affatto:

public FlyBehavior returnBehavior(FlyBehaviorFactory factory, String behaviorType) { 
    return factory.getFlyBehavior(behaviorType); 
} 

E così, hanno la seguente riga di codice:

Duck mallard = new MallardDuck(returnBehavior(flyFactory, "wings")); 

in questo modo, una certa parte del vostro programma non ha bisogno di sapere su che cosa FlyBehaviorFactory da usare. Tuttavia, il tuo metodo main() dovrà ancora specificare alcuni parametri nel metodo returnBehavior per sapere quale factory creerà quale strategia. Quindi, ho ragione nel dire che dovrai ancora modificare main() se ho aggiunto una nuova classe FlyBehavior e volevo aggiungerla come parametro a returnBehavior()?

Si può migliorare ulteriormente questa situazione?

+0

Si dovrebbe dare un'occhiata a [_dependency injection_] (http://en.wikipedia.org/wiki/Dependency_injection) e ai vari framework per esso. – Seelenvirtuose

+0

@Synchro Si prega di leggere: [Cosa devo fare quando qualcuno risponde alla mia domanda] (http://stackoverflow.com/help/someone-answers) – CKing

risposta

0

Nell'esempio corrente, si codificano i parametri passati alla fabbrica e quindi si decide il comportamento su compile time.

Duck mallard = new MallardDuck(returnBehavior(flyFactory, "wings")); 

Questo può essere cambiato a plugin di un particolare comportamento al runtime invece di compile time:

Duck mallard = new MallardDuck(returnBehavior(flyFactory, args[0])); 

Con il cambiamento di cui sopra, non si avrà mai modificare il metodo main. La vostra fabbrica può essere scritto in un modo che throws un exception quando un comportamento ricevuto in fase di esecuzione non è disponibile:

if(behaviorType.equals("wings") { 
    //...create FlyWithWings 
} else{ 
    //throw an appropriate exception indicating that the behavior does not exist 
} 

Detto questo, è inevitabile modificare il codice se viene introdotto un nuovo comportamento. Anche se, questo cambiamento avverrà in un unico posto e il più indietro possibile nella tua applicazione, cioè il tuo factory che è il punto intero di factory in primo luogo. Inoltre, quando si crea un nuovo FlyBehavior, lo si sta estendendo da una classe esistente. Questo è in linea con lo open-closed principle

0

Quello che stai facendo qui è l'iniezione di dipendenza, stai iniettando il FlyBehaviour in Duck. A volte quando si utilizza l'iniezione di dipendenza come questa è possibile avere una catena di iniezioni. Ad esempio, se si desidera che una strategia di velocità venga inserita nel FlyBehaviour, si potrebbe avere qualcosa di simile.

Duck mallard = new MallardDuck(new FlyWithWings(new FastSpeed())); 

Non sarebbe bello avere principale e qualsiasi altra classe che utilizza Anatra di avere di conoscere tutte queste classi e devono cambiare ogni volta uno di questi ha fatto. Una soluzione migliore sarebbe utilizzare un contenitore per le dipendenze che è responsabile della creazione di ciascuna di queste classi. Poi, nel principale si può chiamare qualcosa di simile

Duck mallard = (Duck) Container.get('Duck'); 

Il contenitore è responsabile della creazione di tutte le istanze necessarie per l'iniezione. Quindi per rispondere alla tua domanda dovrai cambiare il tuo codice quando vuoi una nuova strategia, ma almeno in questo modo è solo in un posto invece che nel tuo codice che potrebbe essere molti file.

Problemi correlati