2015-01-11 12 views
5

Ich möchte etwas über Enten Beispiel zu diesem Buch, das mich verwirrt und ich fühle Widersprüche.Ente Beispiel Strategie Muster - Kopf erstes Design Muster

  1. Problem enter image description here

  2. die Schlussfolgerungen enter image description here

Er sagte, "wenn joe neues Verhalten der Ente Super hinzugefügt, er wurde auch das Verhalten hinzufügen, die nicht für sachgemäßer wurden sume Duck Unterklassen "

Aber in der Schlussfolgerung fügte er performFly() und performQuack(); was ist das anders, weil ich denke, dass es gleich he was also adding behavior that was not appropiate for sume Duck subclasses?

** Bild aus dem Buch Kopf erstes Designmuster ** Diese Frage besagt nicht, dass dieses Buch nicht gut ist, dieses Buch ist meiner Meinung nach wirklich gut. Das ist nur ich, der etwas verlangt, was ich nicht aus dem Buch bekommen habe.

+0

Alles, was sie taten, war eine Funktion (quack) zu nehmen und sie in eine separate Klasse zu trennen. Das ist ein bisschen kompliziert. Es wäre besser, eine Unterklasse von Enten namens "FlyingDucks" zu machen und dann Fly() hineinzulegen. Dann erben alle fliegenden Enten diese Klasse. Alternativ dazu erstellt man FLy() abstract und zwingt jede Unterklasse zu definieren, was es bedeutet zu fliegen. Was sie taten, war mehr Arbeit und komplizierter. Jede Unterklasse muss eine Fly-Klasse auswählen, die flyBehavior zugewiesen wird - auch wenn sie nicht fliegen können. – kainaw

+0

Bin ich richtig, wenn ich sage "das Problem" und "die Schlussfolgerung" ist ein Widerspruch? oder ich verstehe es einfach nicht, was er meint? – Kakashi

+0

Es wäre besser Design zu erkennen, dass, wie das (erfundene) Problem Enten ist, eine Gummiente keine Ente ist - sie fliegt nicht, sie schwimmt nicht (außer du schwimmst), usw. Wenn Sie aus irgendeinem Grund wirklich eine Klasse haben wollen, die echte Enten und Gummienten umfasst, dann sollten Sie nach Gemeinsamkeiten in diesen Punkten suchen und diese zu den gemeinsamen Attributen machen; Beginnen Sie nicht mit Attributen, die für einige der Elemente in Ihrem Bereich üblich sind, und passen Sie die anderen an die entsprechenden Komponenten an. – arcy

Antwort

0

In der Schlussfolgerung fügt er zwei neue Klassen, die eine fly() Funktion haben. Die Funktion lässt die Ente jedoch nicht immer fliegen. Gummienten können nicht fliegen, daher verwenden sie eine Instanz der Klasse FlyNoWay. Andere Enten, die fliegen können, benutzen eine Instanz der Klasse. Das Feld flyBehavior in der Duck Klasse würde wahrscheinlich im Konstruktor festgelegt werden. Die Funktion performFly() würde die fly()-Funktion für jede ausgewählte Klasse aufrufen.

Wie von Kainaw in den Kommentaren angegeben, ist dies eine ziemlich komplizierte Lösung. Es kann jedoch immer noch verwendet werden. Angenommen, Sie erstellen ein Programm zum Entwerfen von Enten. Wenn der Benutzer wählt, ob die Ente fliegen kann, kann sie nicht fest codiert werden. Sie könnten einen booleschen Wert erstellen, aber Sie müssen möglicherweise kompliziertere Situationen wie Verhalten behandeln. Möglicherweise benötigen Sie eine WildDuckBehavior Klasse und eine DomesticDuckBehavior, jede mit ihren eigenen Informationen zur Vorgehensweise. Grundsätzlich ist das Beispiel in dem Buch eine vereinfachte Version dessen, wie dies verwendet werden würde.

+0

aber erben die Gummiente immer noch "fliegen", dass "Gummiente" braucht es nicht? – Kakashi

+0

@MuhammadRifkiMockie Ich habe den Graph etwas falsch gelesen, also habe ich die Antwort bearbeitet. Hilft das? – FlyingPiMonster

3

Die Strategie Muster funktioniert, wenn Sie für Komposition der Vererbunghttp://en.wikipedia.org/wiki/Composition_over_inheritance

Dies ist eine gute Praxis ist, weil Sie das Verhalten einer Klasse ändern können, ohne Code zu ändern. Und du brauchst auch keinen riesigen Klassenbaum. Sie können auch das Verhalten einer Klasse dynamisch ändern.

In diesem Beispiel werden die Verhaltensweisen in der übergeordneten Klasse definiert. In der Elternklasse definieren Sie, dass eine Ente ein Flugverhalten und ein Quacksalberverhalten haben kann. Aber das bedeutet nicht, dass die Kinder Klassen quaken oder fliegen müssen.

Sie können eine nichtfliegende Ente haben und wenn Sie "fly" rufen, wird es nichts tun, weil wir ein "nicht fliegendes" Verhalten haben.

Anstatt zu programmieren, was eine Ente in der Klasse macht, können Sie das Verhalten dieser Ente ändern, wann immer Sie wollen.

0

Ich bin kein Guru von Designmustern, aber während ich dieses Buch las, war die erste Sensation, die ich über dieses spezielle Kapitel hatte, dass die Art, wie Interfaces gebaut und dann implementiert wurden, eines der bekannten Programmierprinzipien verletzte : the Interface Segregation Principle (ISP) grundsätzlich ist dieser Grundsatz fest, dass

kein Client auf Methoden angewiesen gezwungen werden sollte es nicht

Da einige Enten nicht verwenden, die die Fliege nicht implementieren fliegen() -Methode selbst es sich brauche es nicht. Ich denke, dass es in diesem speziellen Fall unvermeidlich ist, alle Schnittstellenmethoden zu implementieren, da wir auf der Client-Seite polymorphe Verhaltensweisen verwenden, und wir müssen sicher sein, dass wir alle Methoden zur Verfügung haben, auch wenn sie nicht verwendet werden.