Das Entwurfsmuster Strategie wird häufig als Ersatz für erstklassige Funktionen in Sprachen angesehen, denen diese fehlen.
Angenommen, Sie möchten Funktionen in ein Objekt übertragen. In Java müssten Sie dem Objekt ein anderes Objekt übergeben, das das gewünschte Verhalten kapselt. In einer Sprache wie Ruby übergeben Sie die Funktionalität einfach selbst in Form einer anonymen Funktion.
Allerdings habe ich darüber nachgedacht und festgestellt, dass Strategy möglicherweise mehr bietet als eine reine anonyme Funktion.
Dies liegt daran, dass ein Objekt einen Status enthalten kann, der unabhängig von dem Zeitraum ist, in dem die Methode ausgeführt wird. Eine anonyme Funktion kann jedoch nur den Status halten, der nicht mehr vorhanden ist, sobald die Ausführung der Funktion abgeschlossen ist.
Hat das Strategiemuster in einer objektorientierten Sprache, die erstklassige Funktionen unterstützt, einen Vorteil gegenüber der Verwendung von Funktionen?
quelle
Antworten:
Wenn die Sprache Verweise auf Funktionen unterstützt ( Java seit Version 8 ), sind diese häufig eine gute Alternative für Strategien, da sie in der Regel dasselbe mit weniger Syntax ausdrücken. Es gibt jedoch einige Fälle, in denen ein reales Objekt nützlich sein kann.
Eine Strategie-Schnittstelle kann mehrere Methoden haben. Nehmen wir
RouteFindingStragegy
als Beispiel eine Schnittstelle , die verschiedene Routenfindungsalgorithmen kapselt. Es könnte Methoden wie deklarierenRoute findShortestRoute(Node start, Node destination)
boolean doesRouteExist(Node start, Node destination)
Route[] findAllPossibleRoutes(Node start, Node destination)
Route findShortestRouteToClosestDestination(Node start, Node[] destinations)
Route findTravelingSalesmanRoute(Node[] stations)
was dann alles von der Strategie umgesetzt würde. Einige Routenfindungsalgorithmen ermöglichen möglicherweise interne Optimierungen für einige dieser Anwendungsfälle und andere nicht, sodass der Implementierer entscheiden kann, wie jede dieser Methoden implementiert werden soll.
Ein anderer Fall ist, wenn die Strategie einen inneren Zustand hat. Sicher, in einigen Sprachen können Verschlüsse einen inneren Zustand haben, aber wenn dieser innere Zustand sehr komplex wird, wird es oft eleganter, den Verschluss zu einer vollwertigen Klasse zu befördern.
quelle
Es ist nicht wahr, dass eine anonyme Funktion nur den Status halten kann, der nicht mehr vorhanden ist, wenn die Ausführung der Funktion abgeschlossen ist.
Nehmen Sie das folgende Beispiel in Common Lisp:
Diese Funktion erstellt eine Liste von Zeichenfolgen und stellt jedem Element der Liste einen Zähler voran. Also zum Beispiel aufrufen
gibt
Die Funktion verwendet
number-strings
intern eine anonyme Funktion mit einer Variablencounter
, die den Status (den aktuellen Wert des Zählers) enthält und bei jedem Aufruf der Funktion erneut verwendet wird.Im Allgemeinen können Sie sich einen Abschluss als ein Objekt mit nur einer Methode vorstellen. Alternativ ist ein Objekt eine Sammlung von Closures, die dieselben Closed-Over-Variablen verwenden. Ich bin mir also nicht sicher, ob es Fälle gibt, in denen Sie ein Objekt anstelle eines Abschlusses verwenden müssen: Ich würde argumentieren, dass beide Arten der Betrachtung desselben Musters aus verschiedenen Perspektiven sind.
Insbesondere erfordert das Strategiemuster ein Objekt mit nur einer Methode, sodass ein Abschluss die Aufgabe erfüllen sollte. Aber, wie Philipp in seiner Antwort bemerkt hat, können Sie je nach den Umständen (komplexer Zustand) und Programmiersprachen eine elegantere Lösung erhalten, indem Sie Objekte verwenden.
quelle
let
definieren und dann meinen Abschluss darin definieren. Grundsätzlich hätte ich ein Objekt mit einer Methode on the fly definiert. In einer anderen Sprache (z. B. Java) ist es möglicherweise praktischer (syntaktisch einfacher), ein geeignetes Objekt zu definieren, um den Status zu halten. Ich würde mich also von Fall zu Fall entscheiden.Nur weil zwei Designs das gleiche Problem lösen können, bedeutet dies nicht, dass sie einander direkt ersetzen.
Wenn Sie den Status in einem Funktionsprogramm nachverfolgen müssen, mutieren Sie eine geschlossene Variable nicht, selbst wenn die Sprache dies zulässt. Sie arrangieren den Aufruf einer Funktion, die einen Zustand als Argument verwendet und den neuen Zustand als Rückgabewert zurückgibt.
Ihre Architektur wird sehr unterschiedlich aussehen, aber Sie werden das gleiche Ziel erreichen. Versuchen Sie nicht, die Muster eines Paradigmas direkt auf das andere zu übertragen.
quelle
Strategie ist ein Konzept , ein nützliches Rezept zur Lösung eines bestimmten, wiederkehrenden Problems. Es handelt sich weder um ein Sprachkonstrukt noch um eine Implementierungsform . Ein Abschluss kann verwendet werden, um die Strategie an einem Tag und den Beobachter am nächsten Tag umzusetzen.
Der Begriff Strategie ist vor allem in Gesprächen mit anderen Programmierern nützlich, um Ihre Absichten präzise auszudrücken. Es ist nichts Magisches daran.
quelle