Ist das ein Decorator oder ein Strategie-Muster oder keiner der beiden?

8

Ich habe die folgende Schnittstelle.

PowerSwitch.java

%Vor%

Die obige Schnittstelle sollte aus dem Minimum an Methoden bestehen, aus denen jede andere Funktionalität abgeleitet werden kann, um das Hinzufügen weiterer PowerSwitch-Implementierungen so einfach wie möglich zu machen.

Ich möchte der PowerSwitch-Schnittstelle zur Laufzeit Funktionen hinzufügen (was Dekoratoren tun), indem ich eine Klasse erstelle, die eine Zusammensetzung einer PowerSwitch-Instanz enthält und neue Methoden hinzufügt, wie die beiden toggleOnOff () Methoden unten. Auf diese Weise muss ich die beiden Umschaltmethoden nur einmal implementieren und sie wird auf alle PowerSwitch-Implementierungen angewendet.

Wird dies als eine gute / schlechte Praxis angesehen? Wenn schlecht, irgendwelche anderen Empfehlungen?

Es entspricht nicht wirklich dem Decorator-Muster, da es zusätzliche Methoden hinzufügt. Ist es ein Strategie- oder ein Kompositionsmuster? Oder hat es einen anderen Musternamen? Gibt es so etwas wie einen "Interface Decorator"?

PowerSwitchDecorator.java

%Vor%     
etxalpo 24.01.2012, 08:19
quelle

7 Antworten

7

Jeder Code, der die Methoden toggleOnOff(int) oder toggleOnOff() verwenden möchte, benötigt eine Instanz von PowerSwitchDecorator , nicht PowerSwitch . Diese Art besiegt den Zweck eines Dekorators, der für den Kunden transparent sein sollte.

Wenn Sie möchten, dass alle Implementierungen über diese Methoden verfügen, sollten Sie sie in die Schnittstelle PowerSwitch einfügen.

Dann könnten Sie, wie @Ani vorschlägt, das obige PowerSwitchDecorator ändern, um PowerSwitch zu erweitern, damit Sie dies tun können:

%Vor%

Jetzt haben Sie eine Variable vom Typ PowerSwitch mit den Fähigkeiten von PowerSwitchDecorator .

BEARBEITEN: Beachten Sie, dass Sie nur ein etabliertes Muster verwenden sollten, wenn es Ihren Anforderungen entspricht. Sie können den Ansatz verwenden, den Sie gezeigt haben, wenn es für Sie funktioniert. Keine Notwendigkeit, es in ein bestimmtes Muster zu schuhen.

Um welche Art von Objekt möchten Sie sich kümmern? Möchten Sie solche Methoden in Ihrer API verwenden:

%Vor%

Oder Methoden wie folgt:

%Vor%

(Entschuldigung, das sind keine sehr guten Beispiele)

Wenn Sie das vorherige wollen, dann müssen alle ihre PowerSwitch manuell dekorieren, nur um ein paar bequeme Methoden zu bekommen. Es kann für Sie jetzt bequem sein, aber ich denke, dass es für Benutzer Ihres Codes unbequem sein wird und sie sich wahrscheinlich nicht damit befassen werden. Wenn Sie Letzteres wollen, müssen Sie den Typ PowerSwitchDecorator in Ihren Methodensignaturen verwenden, was bedeutet, dass Sie immer mit PowerSwitchDecorator s und nicht mit root PowerSwitch es umgehen.

    
Gary Buyn 24.01.2012 08:35
quelle
3

Das ist eine gute Übung, wenn Sie Ihre PowerSwitch-Instanz zur Laufzeit verbessern müssen. Ich empfehle Ihnen, die PowerSwitch-Schnittstelle im Dekorateur zu implementieren. Der andere Name des Decorator-Musters ist das Proxy-Muster.

Sie können die erweiterten Methoden in einer anderen Schnittstelle definieren, die Ihre PowerSwitch-Schnittstelle erweitert. Das vermeidet eine Abhängigkeit vom Dekorator, wenn diese erweiterten Methoden aufgerufen werden müssen.

Das Erweitern einer Klasse ist eine gute Übung, wenn Sie ein Verhalten bei der Kompilierung verbessern oder neu definieren müssen.

    
vanadium 24.01.2012 08:24
quelle
0

Es wäre wirklich ein Dekorator, wenn der Dekorator auch die PowerSwitch-Schnittstelle implementiert hätte. Ich würde dies als Objekt-Aggregation charakterisieren.

    
JB Nizet 24.01.2012 08:34
quelle
0

Es ist keines der Muster.

Ein Decorator hat die Absicht, ein Objekt zu umschließen und die bereits vorhandene Funktionalität zu erweitern, wodurch die Schnittstelle für den Client transparent wird. Ein BufferedInputstream ist ein Beispiel. Beachten Sie, dass der Decorator die gleiche Schnittstelle wie den zu umwickelnden Typ implementieren sollte.

%Vor%

Beachten Sie den Unterschied zum Proxy-Muster, bei dem die Hauptzielsetzung darin besteht, den Zugriff auf ein Objekt zu steuern, nicht notwendigerweise durch Umhüllen mit einem anderen Objekt. In diesem Fall würden Sie auch den Proxy die gleiche Schnittstelle implementieren lassen.

    
Thomas Johan Eggum 24.01.2012 08:40
quelle
0

Einige Muster sehen oft ähnlich aus, der Unterschied liegt in der Absicht ihrer Verwendung. Hier ist ein allgemeinerer Thread zu diesem Thema: Wann und wie kann ein Strategie-Muster anstelle eines Dekorationsmusters angewendet werden?

Mit Ihrem Code gibt es noch keinen wirklichen Unterschied. Es sieht wie eine Strategie aus, da der PowerSwitchDecorator lediglich die Arbeit (d. H. Den Algorithmus) an einen PowerSwitch delegiert. Wenn dies Ihre Absicht ist und es alternative PowerSwitches gibt, die auf verschiedene Arten umgeschaltet werden, ist das Strategie-Pattern Ihre Wahl.

Wenn Sie stattdessen eine Reihe von PowerSwitches haben, von denen jeder das Toggeln leicht verbessert (das Toggeln schmückt) und diese PowerSwitches verschachtelt werden können, dann implementieren Sie einen Decorator. Wie bereits erwähnt, benötigen Sie in diesem Fall auch die Dekoratoren als Teil der Typhierarchie.

    
joergl 24.01.2012 08:50
quelle
0

Ich würde sagen, es ist keines der Muster.

Dekorationsmuster

Das Decorator-Muster wird verwendet, um das Verhalten einer vorhandenen Implementierung zu erweitern. Nehmen Sie ein Grafikfenster als Beispiel, Sie möchten vielleicht ein Fenster mit Bildlaufleisten haben. Dann können Sie eine Klasse wie

haben %Vor%

Das Strategie-Muster

Das Strategie-Muster wird verwendet, um verschiedene Dinge abhängig von der gewählten Strategie zu tun. Nehmen wir an, Sie machen Kaffee. Sie könnten etwas wie:

haben %Vor%

und benutze es wie

%Vor%

Lesen Sie die folgenden Links für weitere Informationen:

Tomas Jansson 24.01.2012 09:07
quelle
0

Ihre PowerSwitchDecorator -Klasse ist kein Dekorator. Ihre Implementierung ist in der Nähe von Strategy_pattern , obwohl die Befehle Command_pattern

In Decorator Muster, Decorator implementiert tatsächlich die Schnittstelle (d. h. Component ) und Ihre Klasse macht das nicht gleich.

Schauen Sie sich das Klassendiagramm an

Im obigen Diagramm ist Component eine Schnittstelle. Decorator implementiert Component interface und enthält die Schnittstelle mit Composition . Sehen Sie sich die Mitgliedsvariable an - component .

Beziehen Sie sich zum besseren Verständnis auf diese Fragen:

Decorator-Muster für IO

Beispiel der realen Welt des Strategie-Patterns

    
Ravindra babu 03.06.2016 10:02
quelle