Einführung
Das Strategiemuster definiert eine Familie von Algorithmen und kapselt diese separat, sodass sie untereinander ersetzt werden können. Dieses Modell ermöglicht es, den Algorithmus unabhängig von den Kunden zu ändern, die ihn verwenden.
Zusammensetzung
Abstrakte Strategierolle: Strategieklasse, normalerweise implementiert durch eine Schnittstelle oder abstrakte Klasse.
Spezifische Strategierolle: Paketierung verwandter Algorithmen und Verhaltensweisen.
Umgebungsrolle: Enthält einen Verweis auf eine Strategieklasse, die letztendlich vom Client aufgerufen wird.
Anwendungsszenarien
Mehrere Klassen unterscheiden sich nur in ihrem Verhalten. Sie können den Strategiemodus verwenden, um das spezifische Verhalten, das zur Laufzeit ausgeführt werden soll, dynamisch auszuwählen.
Unterschiedliche Strategien (Algorithmen) müssen in verschiedenen Situationen verwendet werden, oder die Strategie kann in Zukunft auf andere Weise umgesetzt werden.
Verbergen Sie die Implementierungsdetails bestimmter Strategien (Algorithmen) vor Kunden und sind völlig unabhängig voneinander.
Implementierung
Schritte
Definieren Sie die abstrakte Rollenklasse (definieren Sie die gemeinsamen abstrakten Methoden jeder Implementierung)
Definieren Sie die spezifische Strategieklasse (implementieren Sie speziell die Gemeinsame Methode der übergeordneten Klasse)
Umgebungsrollenklasse definieren (gespeicherte Instanz empfangen, Schnittstellenmethode der Richtlinienklasse einheitlich ausführen)
Code
<?php header('Content-Type:text/html;charset=utf-8'); /** * 策略模式演示代码 * * 为了更好地突出“策略”,我们这里以出行为例演示,日常出行大概分为以下几种工具:自驾车,公交车,地铁,火车,飞机,轮船 * * 下面一起看代码,领会何为策略模式 */ /** * Interface Travel 抽象策略角色 * 约定具体方法 */ interface Travel { public function go(); } /** * Class selfDriving 具体策略角色 * 自驾车 */ class bySelfDriving implements Travel { public function go() { echo '我自己开着车出去玩<br>'; } } /** * Class byBus具体策略角色 * 乘公交 */ class byBus implements Travel { public function go() { echo '我乘公交出去玩<br>'; } } /** * Class byMetro 具体策略角色 * 乘地铁 */ class byMetro implements Travel { public function go() { echo '我乘地铁出去玩<br>'; } } /** * Class byTrain 具体策略角色 * 乘火车 */ class byTrain implements Travel { public function go() { echo '我乘火车出去玩<br>'; } } /** * Class byAirplane 具体策略角色 * 乘飞机 */ class byAirplane implements Travel { public function go() { echo '我乘飞机出去玩<br>'; } } /** * Class bySteamship 具体策略角色 * 乘轮船 */ class bySteamship implements Travel { public function go() { echo '我乘轮船出去玩<br>'; } } /** * Class Mine 环境角色 */ class Mine{ private $_strategy; private $_isChange = false; /** * 构造方法 * 此处使用到了依赖注入和类型约束的概念,详情请参考 * 1.聊一聊PHP的依赖注入(DI) 和 控制反转(IoC) * @link https://segmentfault.com/a/1190000007209266 * 2.浅谈PHP的类型约束 * @link https://segmentfault.com/a/1190000007226476 * * @param Travel $travel */ public function __construct(Travel $travel) { $this->_strategy = $travel; } /** * 改变出行方式 * * @param Travel $travel */ public function change(Travel $travel) { $this->_strategy = $travel; $this->_isChange = true; } public function goTravel() { if ($this->_isChange) { echo '现在改变主意,'; $this->_strategy->go(); } else { $this->_strategy->go(); } } } /** * 客户端使用 */ $strategy = new Mine(new byBus()); // 乘公交 $strategy->goTravel(); // 乘地铁 $strategy->change(new byMetro()); $strategy->goTravel(); // 自驾车 $strategy->change(new bySelfDriving()); $strategy->goTravel(); // 其他根据具体应用选择实现
Ergebnis ausführen
Ich fahre mit dem Bus raus
Jetzt habe ich es mir anders überlegt, bin mit der U-Bahn gefahren
Jetzt habe ich es mir anders überlegt, ich bin mit dem Auto rausgefahren
Vor- und Nachteile
Vorteile
Strategiemuster bieten eine Möglichkeit, verwandte Algorithmusfamilien zu verwalten. Eine Hierarchie von Richtlinienklassen definiert eine Familie von Algorithmen oder Verhaltensweisen. Durch die ordnungsgemäße Verwendung der Vererbung kann gemeinsamer Code an die übergeordnete Klasse übertragen werden, wodurch eine Duplizierung des Codes vermieden wird.
Das Strategiemuster bietet eine Möglichkeit, die Vererbungsbeziehung zu ersetzen. Die Vererbung kann mehrere Algorithmen oder Verhaltensweisen verarbeiten. Wenn Sie das Strategiemuster nicht verwenden, verfügt die Umgebungsklasse, die einen Algorithmus oder ein Verhalten verwendet, möglicherweise über einige Unterklassen, wobei jede Unterklasse einen anderen Algorithmus oder ein anderes Verhalten bereitstellt. Auf diese Weise werden jedoch die Benutzer des Algorithmus oder Verhaltens mit dem Algorithmus oder Verhalten selbst verwechselt. Die Logik, die bestimmt, welcher Algorithmus verwendet oder welches Verhalten angewendet werden soll, vermischt sich mit der Logik des Algorithmus oder Verhaltens, sodass es unmöglich wird, sich unabhängig weiterzuentwickeln. Durch Vererbung ist es unmöglich, Algorithmen oder Verhalten dynamisch zu ändern.
Durch die Verwendung des Strategiemusters kann die Verwendung mehrerer bedingter Übertragungsanweisungen vermieden werden. Mehrfachübertragungsanweisungen sind nicht einfach zu pflegen. Sie vermischen die Logik des zu übernehmenden Algorithmus oder Verhaltens und listen sie alle in einer Mehrfachübertragungsanweisung auf. Sie sind primitiver und rückständiger als die Vererbungsmethode. .
Nachteile
Der Kunde muss alle Versicherungsklassen kennen und entscheiden, welche er verwenden möchte. Das bedeutet, dass der Kunde die Unterschiede zwischen diesen Algorithmen verstehen muss, um zum richtigen Zeitpunkt die passende Algorithmusklasse auszuwählen. Mit anderen Worten: Das Strategiemuster ist nur dann geeignet, wenn der Kunde alle Algorithmen oder Verhaltensweisen kennt.
Das Strategiemuster erstellt viele Strategieklassen, und jede spezifische Strategieklasse generiert eine neue Klasse. Manchmal ist es möglich, eine Richtlinienklasse so zu gestalten, dass sie gemeinsam genutzt werden kann, indem der umgebungsabhängige Status auf dem Client gespeichert wird, sodass Richtlinienklasseninstanzen von verschiedenen Clients verwendet werden können. Mit anderen Worten: Sie können das Flyweight-Muster verwenden, um die Anzahl der Objekte zu reduzieren.