2015-04-26 21 views
5

Ich nehme eine Designmusterklasse in der Schule und habe einige Kapitel von Head First Design Patterns gelesen. Was ich herausfinden möchte, ist, bis zu welchem ​​Grad Designmuster das Umschreiben von bestehendem Code verhindern können.Bis zu welchem ​​Grad können Sie verhindern, dass bei der Verwendung von Entwurfsmustern der vorhandene Code geändert wird?

Nehmen wir Duck Klassen und FlyBehavior Klassen zum Beispiel. Ich habe in public static void main(String[] args) den folgenden Code:

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

Bin ich zu Recht sagen, dass es unvermeidlich ist, dass Sie zu finden Ihre main() Methode ändern, wenn Sie eine neue Strategie hinzufügen? Auf diese Weise sind Sie sind ändern bestehenden Code, richtig? Ich beziehe mich insbesondere auf den Teil, wo eine konkrete Strategie Klasse erwähnt wird: new FlyWithWings().

Wenn Sie die Factory-Methode Muster in Ihrem Code implementiert, Sie verhindern könnten eine konkrete Klasse, die (FlyWithWings) von überhaupt erwähnt werden:

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

Und so haben die folgende Codezeile:

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

auf diese Weise wird ein bestimmter Teil des Programms muss wissen nicht, was FlyBehaviorFactory zu verwenden. Ihre Methode main() muss jedoch bestimmte Parameter in der Methode returnBehavior angeben, um zu ermitteln, welche Factory welche Strategie erstellt. Also, bin ich richtig zu sagen, dass Sie noch ändern müssen main(), wenn ich eine neue FlyBehavior-Klasse hinzugefügt, und wollte das als Parameter zu returnBehavior() hinzufügen?

Kann man diese Situation noch verbessern?

+0

Sie sollten sich [_dependency injection_] (http://en.wikipedia.org/wiki/Dependency_injection) und die verschiedenen Frameworks dafür ansehen. – Seelenvirtuose

+0

@Synchro Bitte lesen Sie: [Was soll ich tun, wenn jemand meine Frage beantwortet] (http://stackoverflow.com/help/someone-answers) – CKing

Antwort

0

Im aktuellen Beispiel codieren Sie die an Ihre Fabrik übergebenen Parameter hart und entscheiden somit über das Verhalten bei compile time.

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

Dies kann ein bestimmtes Verhalten bei runtime statt compile time Plugin geändert werden:

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

Mit der obigen Änderung, werden Sie nie Ihre main Methode ändern müssen. Ihre Fabrik kann in einer Weise geschrieben werden, die es throws ein exception, wenn ein Verhalten zur Laufzeit empfangen ist nicht verfügbar:

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

Davon abgesehen, ist es unvermeidlich, den Code zu ändern, wenn ein neues Verhalten eingeführt wird. Obwohl, diese Änderung wird an einem einzigen Ort und so weit wie möglich in Ihrer Anwendung, d. H. Ihre factory, die der ganze Punkt von factory an erster Stelle ist. Wenn Sie eine neue FlyBehavior erstellen, tun Sie dies, indem Sie von einer vorhandenen Klasse erweitern. Dies ist inline mit der open-closed principle

0

Was Sie hier tun, ist die Abhängigkeit Injektion, Sie injizieren die FlyBehaviour in Ente. Manchmal, wenn Sie eine solche Abhängigkeitsinjektion verwenden, können Sie eine Kette von Injektionen haben. Zum Beispiel, wenn Sie wollten, dass eine Geschwindigkeitsstrategie in FlyBehaviour eingefügt wird, könnten Sie etwas ähnliches haben.

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

Es wäre nicht schön, Haupt zu haben und andere Klasse, die Ente nutzt über alle diese Klassen zu haben, zu wissen, und haben jedes Mal eine dieser ändern. Eine bessere Lösung wäre die Verwendung eines Dependency-Injection-Containers, der für die Erstellung jeder dieser Klassen zuständig ist. Dann können Sie in der Hauptsache einfach so etwas anrufen

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

Der Container ist verantwortlich für die Erstellung aller Instanzen für die Injektion benötigt. Um Ihre Frage zu beantworten, müssen Sie Ihren Code ändern, wenn Sie eine neue Strategie wünschen, aber zumindest auf diese Weise ist es nur an einer Stelle statt in Ihrem gesamten Code, der viele Dateien enthalten könnte.