Was sind die Unterschiede zwischen dem Strategie-Entwurfsmuster und dem staatlichen Entwurfsmuster? Ich habe einige Artikel im Internet durchgesehen, konnte aber den Unterschied nicht klar erkennen.
Kann jemand bitte den Unterschied in Laienbegriffen erklären?
design-patterns
strategy-pattern
state-pattern
Chin Tser
quelle
quelle
Antworten:
Ehrlich gesagt sind die beiden Muster in der Praxis ziemlich ähnlich, und der entscheidende Unterschied zwischen ihnen variiert in der Regel je nachdem, wen Sie fragen. Einige beliebte Optionen sind:
Eine "klassische" Implementierung würde entweder Status oder Strategie für jedes Element auf der Liste entsprechen, aber Sie stoßen auf Hybride, die eine Mischung aus beiden aufweisen. Ob eine bestimmte eher staatlich oder strategisch ist, ist letztendlich eine subjektive Frage.
quelle
getStatus()
Methode, die je nach Status des Objekts unterschiedliche Status zurückgibt, aber der Aufrufer der Methode muss nicht unterschiedlich codiert sein, um jeden potenziellen Status zu berücksichtigen.quelle
Der Unterschied liegt einfach darin, dass sie verschiedene Probleme lösen:
Die Konstrukte zur Erreichung dieser unterschiedlichen Ziele sind jedoch sehr ähnlich; Beide Muster sind Beispiele für Kompositionen mit Delegation.
Einige Beobachtungen zu ihren Vorteilen:
Durch die Verwendung des Staates wird Muster der Zustandshalte (Kontext) Klasse aus der Kenntnis erleichtert , was Staat oder geben es ist und was besagt , oder Arten , die verfügbar sind. Dies bedeutet, dass die Klasse dem Open-Closed-Design-Prinzip (OCP) folgt: Die Klasse ist geschlossen, um zu ändern, welche Zustände / Typen vorhanden sind, aber die Zustände / Typen sind für Erweiterungen offen.
Durch die Verwendung des Strategie - Musters des Algorithmus betriebene (Kontext) Klasse aus der Kenntnis erleichtert wird , wie eine bestimmte Aufgabe auszuführen (- der „Algorithmus“). Dieser Fall schafft auch eine Einhaltung der OCP; Die Klasse ist wegen Änderungen bezüglich der Ausführung dieser Aufgabe geschlossen, aber das Design ist sehr offen für Ergänzungen anderer Algorithmen zur Lösung dieser Aufgabe.
Dies verbessert wahrscheinlich auch die Einhaltung des Single-Responsibility-Prinzips (SRP) durch die Kontextklasse. Ferner wird der Algorithmus leicht für die Wiederverwendung durch andere Klassen verfügbar.
quelle
Designmuster sind keine wirklichen "Laien" -Konzepte, aber ich werde versuchen, es so klar wie möglich zu machen. Jedes Entwurfsmuster kann in drei Dimensionen betrachtet werden:
Vergleichen wir Zustand und Strategie.
Problem, das das Muster löst
Der Status wird in einem von zwei Fällen verwendet [GoF-Buch S. 306] :
Wenn Sie sicherstellen möchten, dass Sie tatsächlich das Problem haben, das das Zustandsmuster löst, sollten Sie in der Lage sein, die Zustände des Objekts mithilfe einer endlichen Zustandsmaschine zu modellieren . Ein angewandtes Beispiel finden Sie hier .
Jeder Zustandsübergang ist eine Methode in der Zustandsschnittstelle. Dies bedeutet, dass Sie für ein Design über Zustandsübergänge ziemlich sicher sein müssen, bevor Sie dieses Muster anwenden. Andernfalls müssen beim Hinzufügen oder Entfernen von Übergängen die Schnittstelle und alle Klassen, die sie implementieren, geändert werden.
Ich persönlich fand dieses Muster nicht so nützlich. Sie können Finite-State-Maschinen jederzeit mithilfe einer Nachschlagetabelle implementieren (dies ist keine OO-Methode, funktioniert aber recht gut).
Die Strategie wird für Folgendes verwendet [GoF-Buch S. 316] :
Der letzte Fall, in dem die Strategie angewendet werden soll, bezieht sich auf ein Refactoring, das als Ersetzen bedingt durch Polymorphismus bezeichnet wird .
Zusammenfassung: Staat und Strategie lösen sehr unterschiedliche Probleme. Wenn Ihr Problem nicht mit einer endlichen Zustandsmaschine modelliert werden kann, ist das wahrscheinliche Zustandsmuster nicht geeignet. Wenn es bei Ihrem Problem nicht darum geht, Varianten eines komplexen Algorithmus zu kapseln, gilt die Strategie nicht.
Statische Struktur des Musters
Der Status hat die folgende UML-Klassenstruktur:
Die Strategie hat die folgende UML-Klassenstruktur:
Zusammenfassung: In Bezug auf die statische Struktur sind diese beiden Muster größtenteils identisch. Tatsächlich sind Mustererkennungswerkzeuge wie dieses der Ansicht, dass " die Struktur der [...] Muster identisch ist und ihre Unterscheidung durch einen automatischen Prozess verhindert (z. B. ohne Bezugnahme auf konzeptionelle Informationen) ".
Es kann jedoch einen großen Unterschied geben, wenn ConcreteStates die Zustandsübergänge selbst bestimmen (siehe die Assoziationen " möglicherweise bestimmen " im obigen Diagramm). Dies führt zu einer Kopplung zwischen konkreten Zuständen. Beispiel (siehe nächster Abschnitt), Status A bestimmt den Übergang zu Status B. Wenn die Context-Klasse den Übergang zum nächsten konkreten Status entscheidet, verschwinden diese Abhängigkeiten.
Dynamik des Musters
Wie im Abschnitt oben Problem erwähnt, Staat bedeutet , dass Verhaltensänderungen zur Laufzeit in Abhängigkeit von einem gewissen Zustand eines Objekts. Daher ist der Begriff der staatlichen transitioning Anwendung findet, wie bei der Beziehung der diskutierten finite Zustandsmaschine . [GoF] erwähnt, dass Übergänge entweder in den ConcreteState-Unterklassen oder an einem zentralen Ort (z. B. einem tabellenbasierten Ort) definiert werden können.
Nehmen wir eine einfache endliche Zustandsmaschine an:
Angenommen, die Unterklassen entscheiden über den Statusübergang (durch Rückgabe des nächsten Statusobjekts), sieht die Dynamik ungefähr so aus:
Um die Dynamik der Strategie zu zeigen , ist es nützlich, ein echtes Beispiel auszuleihen .
Zusammenfassung : Jedes Muster verwendet einen polymorphen Aufruf, um je nach Kontext etwas zu tun. Im Zustandsmuster bewirkt der polymorphe Aufruf (Übergang) häufig eine Änderung des nächsten Zustands . Im Strategiemuster ändert der polymorphe Anruf normalerweise nicht den Kontext (z. B. bedeutet das einmalige Bezahlen mit Kreditkarte nicht, dass Sie das nächste Mal mit PayPal bezahlen). Auch hier wird die Dynamik des Zustandsmusters durch die entsprechende Fininte-Zustandsmaschine bestimmt, was (für mich) für die korrekte Anwendung dieses Musters wesentlich ist.
quelle
Das Strategiemuster umfasst das Verschieben der Implementierung eines Algorithmus aus einer Hosting-Klasse und das Einfügen in eine separate Klasse. Dies bedeutet, dass die Hostklasse nicht die Implementierung jedes Algorithmus selbst bereitstellen muss, was wahrscheinlich zu unreinem Code führt.
Sortieralgorithmen werden normalerweise als Beispiel verwendet, da sie alle dasselbe tun (sortieren). Wenn jeder unterschiedliche Sortieralgorithmus in eine eigene Klasse eingeordnet wird, kann der Client leicht auswählen, welcher Algorithmus verwendet werden soll, und das Muster bietet eine einfache Möglichkeit, darauf zuzugreifen.
Das Statusmuster umfasst das Ändern des Verhaltens eines Objekts, wenn sich der Status des Objekts ändert. Dies bedeutet, dass die Hostklasse nicht die Implementierung des Verhaltens für alle verschiedenen Zustände bereitstellt, in denen sie sich befinden kann. Die Hostklasse kapselt normalerweise eine Klasse, die die in einem bestimmten Zustand erforderliche Funktionalität bereitstellt, und wechselt zu einer anderen Klasse wenn sich der Zustand ändert.
quelle
Stellen Sie sich ein IVR-System (Interactive Voice Response) vor, das Kundenanrufe verarbeitet. Möglicherweise möchten Sie es so programmieren, dass es Kunden behandelt:
Um mit dieser Situation umzugehen, können Sie ein Statusmuster verwenden .
Dieser Prozess der Verbindung eines Kunden mit einem Support-Manager kann selbst mithilfe eines Strategiemusters implementiert werden, bei dem die Führungskräfte anhand einer der folgenden Kriterien ausgewählt werden:
Das Strategiemuster entscheidet darüber, wie eine Aktion ausgeführt werden soll, und das Statusmuster entscheidet darüber, wann sie ausgeführt werden sollen.
quelle
Strategie repräsentiert Objekte, die etwas "tun", mit denselben Anfangs- und Endergebnissen, aber intern unter Verwendung unterschiedlicher Methoden. In diesem Sinne sind sie analog zur Darstellung der Implementierung eines Verbs. Das Zustandsmuster OTOH verwendet Objekte, die etwas "sind" - den Zustand einer Operation. Sie können zwar auch Operationen mit diesen Daten darstellen, sind jedoch eher mit der Darstellung eines Substantivs als mit einem Verb vergleichbar und auf Zustandsautomaten zugeschnitten.
quelle
Strategie: Die Strategie ist festgelegt und besteht normalerweise aus mehreren Schritten. (Das Sortieren stellt nur einen Schritt dar und ist daher ein sehr schlechtes Beispiel, da es zu primitiv ist, um den Zweck dieses Musters zu verstehen.) Ihre "Hauptroutine" in der Strategie besteht darin, einige abstrakte Methoden aufzurufen. Beispiel: "Raumstrategie eingeben", "Hauptmethode" ist goThroughDoor (), was wie folgt aussieht: ApproachDoor (), if (Locked ()) openLock (); offene Tür(); enterRoom (); Wende(); Tür schließen(); if (wasLocked ()) lockDoor ();
Nun können Unterklassen dieses allgemeinen "Algorithmus" zum Bewegen von einem Raum in einen anderen Raum durch eine mögliche verschlossene Tür die Schritte des Algorithmus implementieren.
Mit anderen Worten, die Unterklasse der Strategie ändert nicht die grundlegenden Algorithmen, sondern nur einzelne Schritte.
DAS OBEN ist ein Muster der Vorlagenmethode. Fügen Sie nun zusammengehörige Schritte (Entsperren / Sperren und Öffnen / Schließen) in ihre eigenen Implementierungsobjekte ein und delegieren Sie sie an diese. Beispielsweise sind ein Schloss mit einem Schlüssel und ein Schloss mit einer Codekarte zwei Arten von Schlössern. Delegieren Sie von der Strategie an die "Step" -Objekte. Jetzt haben Sie ein Strategiemuster.
Ein Zustandsmuster ist etwas völlig anderes.
Sie haben ein Wrapping-Objekt und das Wrapped-Objekt. Der eingewickelte ist der "Staat". Auf das Statusobjekt wird nur über seinen Wrapper zugegriffen. Jetzt können Sie das umschlossene Objekt jederzeit ändern, sodass der Wrapper seinen Status oder sogar seine "Klasse" oder seinen Typ zu ändern scheint.
ZB haben Sie einen Anmeldedienst. Es akzeptiert einen Benutzernamen und ein Passwort. Es gibt nur eine Methode: logon (String userName, String passwdHash). Anstatt selbst zu entscheiden, ob eine Anmeldung akzeptiert wird oder nicht, delegiert sie die Entscheidung an ein Statusobjekt. Dieses Statusobjekt prüft normalerweise nur, ob die Benutzer / Pass-Kombination gültig ist, und führt eine Anmeldung durch. Jetzt können Sie den "Checker" gegen einen austauschen, bei dem sich nur privilegierte Benutzer anmelden können (z. B. während der Wartungszeit), oder gegen einen, bei dem sich niemand anmelden kann. Das heißt, der "Checker" drückt den "Anmeldestatus" des Systems aus.
Der wichtigste Unterschied ist: Wenn Sie eine Strategie gewählt haben, bleiben Sie dabei, bis Sie damit fertig sind. Das heißt, Sie nennen es "Hauptmethode" und solange diese ausgeführt wird, ändern Sie nie die Strategie. OTOH In einer Zustandsmustersituation während der Laufzeit Ihres Systems ändern Sie den Zustand beliebig, wie Sie es für richtig halten.
quelle
Das Strategiemuster wird verwendet, wenn Sie mehrere Algorithmen für eine bestimmte Aufgabe haben und der Client die tatsächliche Implementierung festlegt, die zur Laufzeit verwendet werden soll.
UML-Diagramm aus dem Wiki Strategiemusterartikel:
Hauptmerkmale:
Weitere Informationen und Beispiele aus der Praxis finden Sie in diesem Beitrag:
Beispiel aus der Praxis für das Strategiemuster
Mit dem Statusmuster kann ein Objekt sein Verhalten ändern, wenn sich sein interner Status ändert
UML-Diagramm aus dem Wiki- Statusmusterartikel:
Wenn wir das Verhalten eines Objekts basierend auf seinem Status ändern müssen, können wir eine Statusvariable im Objekt haben und den if-else-Bedingungsblock verwenden, um verschiedene Aktionen basierend auf dem Status auszuführen. Das Zustandsmuster wird verwendet, um einen systematischen und verlustgekoppelten Weg bereitzustellen, um dies durch Kontext- und Zustandsimplementierungen zu erreichen .
Weitere Informationen finden Sie in diesem journaldev- Artikel.
Hauptunterschiede zu Sourcemaking- und Journaldev- Artikeln:
quelle
In Laiensprache,
Im Strategiemuster gibt es keine Zustände oder alle haben denselben Zustand. Alles, was man hat, sind verschiedene Arten, eine Aufgabe auszuführen, wie verschiedene Ärzte dieselbe Krankheit desselben Patienten mit demselben Zustand auf unterschiedliche Weise behandeln.
Im Zustandsmuster gibt es subjektiv Zustände wie den aktuellen Zustand des Patienten (z. B. hohe Temperatur oder niedrige Temperatur), auf deren Grundlage die nächste Vorgehensweise (Verschreibung von Medikamenten) festgelegt wird. Und ein Zustand kann zu einem anderen Zustand führen, also gibt es einen Zustand Abhängigkeit angeben (Zusammensetzung technisch).
Wenn wir technisch versuchen, es zu verstehen, basierend auf dem Codevergleich von beiden, verlieren wir möglicherweise die Subjektivität der Situation, da beide sehr ähnlich aussehen.
quelle
Beide Muster delegieren an eine Basisklasse mit mehreren Ableitungen, aber nur im Statusmuster enthalten diese Ableitungsklassen einen Verweis auf die Kontextklasse.
Eine andere Sichtweise ist, dass das Strategiemuster eine einfachere Version des Zustandsmusters ist. ein Untermuster, wenn Sie möchten. Es hängt wirklich davon ab, ob die abgeleiteten Zustände Verweise auf den Kontext enthalten sollen oder nicht (dh, ob sie Methoden für den Kontext aufrufen sollen).
Für weitere Informationen: Robert C Martin (& Micah Martin) beantworten dies in ihrem Buch "Agile Prinzipien, Muster und Praktiken in C #". ( http://www.amazon.com/Agile-Principles-Patterns-Practices-C/dp/0131857258 )
quelle
Dies ist eine ziemlich alte Frage, aber ich habe auch nach den gleichen Antworten gesucht und das habe ich entdeckt.
Betrachten Sie für das Statusmuster ein Beispiel für die Schaltfläche "Medial Player Play". Wenn wir spielen, beginnt es zu spielen und macht den Kontext darauf aufmerksam, dass es spielt. Jedes Mal, wenn der Client eine Spieloperation ausführen möchte, überprüft er den aktuellen Status des Spielers. Jetzt weiß der Client, dass der Status des Objekts über das Kontextobjekt abgespielt wird, und ruft die Aktionsmethode für Objekte mit Pausenstatusobjekten auf. Der Teil des Kunden, der den Status erkennt und weiß, in welchem Status er Maßnahmen ergreifen muss, kann automatisiert werden.
https://www.youtube.com/watch?v=e45RMc76884 https://www.tutorialspoint.com/design_pattern/state_pattern.htm
Im Fall des Strategiemusters entspricht die Anordnung des Klassendiagramms dem Zustandsmuster. Der Kunde kommt zu dieser Vereinbarung, um eine Operation durchzuführen. Das heißt, anstelle der unterschiedlichen Zustände gibt es unterschiedliche Algorithmen, beispielsweise unterschiedliche Analysen, die für das Muster durchgeführt werden müssen. Hier teilen die Clients dem Kontext mit, was sie mit welchem Algorithmus (Business Defined Custom Algorithmus) tun möchten, und führen dies dann aus.
https://www.tutorialspoint.com/design_pattern/strategy_pattern.htm
Beide implementieren das Open-Close-Prinzip, sodass der Entwickler dem Statusmuster und dem neuen Algorithmus neue Zustände hinzufügen kann.
Der Unterschied besteht jedoch darin, was sie verwendet werden. Dies ist ein Zustandsmuster, mit dem unterschiedliche Logik basierend auf einem Zustand des Objekts ausgeführt wird. Und im Falle einer Strategie andere Logik.
quelle
Der Zustand weist einige Abhängigkeiten innerhalb der vom Staat abgeleiteten Klassen auf: Wie ein Staat weiß, dass andere Zustände nach ihm kommen. Zum Beispiel kommt der Sommer nach dem Winter für jeden Jahreszeitzustand oder der Lieferzustand nach dem Einzahlungsstatus für den Einkauf.
Andererseits hat Strategy keine solchen Abhängigkeiten. Hier kann jede Art von Status basierend auf dem Programm- / Produkttyp initialisiert werden.
quelle
Der Unterschied wird unter http://c2.com/cgi/wiki?StrategyPattern erläutert . Ich habe das Strategiemuster verwendet, um die Auswahl verschiedener Algorithmen innerhalb eines Gesamtrahmens für die Analyse von Daten zu ermöglichen. Dadurch können Sie Algorithmen hinzufügen, ohne die allgemeinen Frameworks und deren Logik ändern zu müssen.
Ein typisches Beispiel ist, dass Sie ein Framework zur Optimierung einer Funktion haben. Das Framework richtet die Daten und Parameter ein. Mit dem Strategiemuster können Sie Algorithmen wie Sttepest-Abfahrten, konjugierte Gradienten, BFGS usw. auswählen, ohne das Framework zu ändern.
quelle
Sowohl Strategie als auch Staatsmuster haben die gleiche Struktur. Wenn Sie sich das UML-Klassendiagramm für beide Muster ansehen, sehen sie genau gleich aus, aber ihre Absicht ist völlig unterschiedlich. Das Zustandsentwurfsmuster wird verwendet, um den Zustand eines Objekts zu definieren und zu verwalten, während das Strategiemuster verwendet wird, um einen Satz austauschbarer Algorithmen zu definieren und dem Client die Auswahl eines davon zu ermöglichen. Das Strategiemuster ist also ein Client-gesteuertes Muster, während Object den Status selbst verwalten kann.
quelle
Kurz gesagt, mit dem Strategiemuster können wir ein Verhalten im laufenden Betrieb festlegen. Mit dem Statusmuster können wir sicher sein, dass ein Objekt sein Verhalten intern mit der Änderung seines Status ändert.
quelle
Wenn Sie ein Projekt haben, das in zwei Aufgaben unterteilt werden kann:
Aufgabe 1: Sie können einen von zwei verschiedenen Algorithmen verwenden, um Folgendes zu erreichen: alg1, alg2
Aufgabe 2: Sie können einen von drei verschiedenen Algorithmen verwenden, um Folgendes zu erreichen: alg3, alg4, alg5
alg1 und alg2 sind austauschbar; alg3, alg4 und alg5 sind austauschbar.
Die Auswahl des Algorithmus, der in Aufgabe 1 und Aufgabe 2 ausgeführt werden soll, hängt von den folgenden Zuständen ab:
Zustand 1: Sie benötigen alg1 in Aufgabe 1 und alg3 in Aufgabe 2
Zustand 2: Sie benötigen alg2 in Aufgabe 1 und alg5 in Aufgabe 2
Ihr Kontext kann das Statusobjekt von Status 1 in Status 2 ändern. Dann wird Ihre Aufgabe von alg2 und alg5 anstelle von alg1 und alg3 ausgeführt.
Sie können weitere austauschbare Algorithmen für Aufgabe 1 oder Aufgabe 2 hinzufügen. Dies ist ein Strategiemuster.
Sie können in Aufgabe 1 und Aufgabe 2 mehr Zustände mit unterschiedlichen Kombinationen von Algorithmen haben. Mit dem Zustandsmuster können Sie von einem Zustand in einen anderen wechseln und verschiedene Kombinationen von Algorithmen ausführen.
quelle
'Strategie' ist nur ein Algorithmus, den Sie unter verschiedenen Umständen nach Bedarf ändern können und der etwas für Sie verarbeitet. Ex. Sie können auswählen, wie eine Datei komprimiert werden soll. zip oder rar ... in einer Methode.
Aber 'State' KANN Ihr gesamtes Objektverhalten ändern, wenn es sich ändert. Sogar es kann andere Felder ändern ... deshalb hat es einen Verweis auf seinen Besitzer. Sie sollten beachten, dass das Ändern eines Objektfelds das Objektverhalten überhaupt ändern kann. Ex. Wenn Sie State0 in obj in State1 ändern, ändern Sie eine Ganzzahl in 10. Wenn wir also obj.f0 () aufrufen, das einige Berechnungen durchführt und diese Ganzzahl verwendet, wirkt sich dies auf das Ergebnis aus.
quelle