Im vorherigen Artikel „Verstehen Sie den Prototypmodus in PHP in einem Artikel“ haben wir den Prototypmodus in PHP vorgestellt. Dieser Artikel führt Sie zum Verständnis des Befehlsmodus in PHP.
Befehlsmodus, auch Aktions- oder Transaktionsmodus genannt. In vielen Lehrbüchern werden Restaurants als Beispiel verwendet. Als Kunden sind wir die Besteller, die Kellner sind die Empfänger dieser Bestellung, das Menü ist die eigentliche Bestellung und der Koch ist der Ausführer dieser Bestellung.
Was löst dieses Modell? Wenn Sie das Menü ändern möchten, müssen Sie es nur dem Kellner mitteilen, und er wird es dem Koch mitteilen. Mit anderen Worten: Wir haben die Entkopplung von Kunden und Köchen erreicht. Das ist die Entkopplung von Aufrufern und Implementierern.
Natürlich können viele Entwurfsmuster dies tun, aber das Befehlsmuster kann es einem Befehlsempfänger ermöglichen, mehrere Befehle zu implementieren (Kellner, der Bestellungen aufgibt, Getränke holt, Gerichte serviert) oder einen Befehl an mehrere Realizer weiterzuleiten (heiß Tellerkoch, Kalttellerkoch, Hauptgerichtskoch). Hier kommt das Befehlsmuster wirklich ins Spiel! !
GoF-Definition: Kapseln Sie eine Anforderung als Objekt, sodass Sie Clients mit unterschiedlichen Anforderungen parametrisieren, Anforderungen in die Warteschlange stellen oder Anforderungsprotokolle aufzeichnen und rückgängig machende Operationen unterstützen können.
GoF-Klasse Diagramm
Code-Implementierung
class Invoker { public $command; public function __construct($command) { $this->command = $command; } public function exec() { $this->command->execute(); } }
Zuerst definieren wir einen Empfänger eines Befehls, oder besser gesagt, einen Anforderer eines Befehls. Die englische Definition dieses Wortes im Klassendiagramm lautet „supplicant“. Das heißt, es initiiert und führt Befehle aus.
abstract class Command { protected $receiver; public function __construct(Receiver $receiver) { $this->receiver = $receiver; } abstract public function execute(); } class ConcreteCommand extends Command { public function execute() { $this->receiver->action(); } }
Der nächste Schritt ist der Befehl, der unser „Menü“ darstellt. Der Zweck dieses Befehls besteht darin, zu definieren, wer der eigentliche Ausführende ist.
class Receiver { public $name; public function __construct($name) { $this->name = $name; } public function action() { echo $this->name . '命令执行了!', PHP_EOL; } }
Der Taker, also der Executor, ist die Person, die den Auftrag tatsächlich ausführt.
// 准备执行者 $receiverA = new Receiver('A'); // 准备命令 $command = new ConcreteCommand($receiverA); // 请求者 $invoker = new Invoker($command); $invoker->exec();
Um den Kunden anzurufen, müssen wir den Testamentsvollstrecker kontaktieren, das heißt, ein Restaurant mit einem guten Koch auswählen (Empfänger), dann die Bestellung vorbereiten, also das Menü (Befehl), und sie schließlich dem Kellner übergeben (Anrufer).
Vollständiger Code: https://github.com/zhangyue0503/designpatterns-php/blob/master/09.command/source/command.php
<?php class Invoker { private $command = []; public function setCommand(Command $command) { $this->command[] = $command; } public function exec() { if(count($this->command) > 0){ foreach ($this->command as $command) { $command->execute(); } } } public function undo() { if(count($this->command) > 0){ foreach ($this->command as $command) { $command->undo(); } } } } abstract class Command { protected $receiver; protected $state; protected $name; public function __construct(Receiver $receiver, $name) { $this->receiver = $receiver; $this->name = $name; } abstract public function execute(); } class ConcreteCommand extends Command { public function execute() { if (!$this->state || $this->state == 2) { $this->receiver->action(); $this->state = 1; } else { echo $this->name . '命令正在执行,无法再次执行了!', PHP_EOL; } } public function undo() { if ($this->state == 1) { $this->receiver->undo(); $this->state = 2; } else { echo $this->name . '命令未执行,无法撤销了!', PHP_EOL; } } } class Receiver { public $name; public function __construct($name) { $this->name = $name; } public function action() { echo $this->name . '命令执行了!', PHP_EOL; } public function undo() { echo $this->name . '命令撤销了!', PHP_EOL; } } // 准备执行者 $receiverA = new Receiver('A'); $receiverB = new Receiver('B'); $receiverC = new Receiver('C'); // 准备命令 $commandOne = new ConcreteCommand($receiverA, 'A'); $commandTwo = new ConcreteCommand($receiverA, 'B'); $commandThree = new ConcreteCommand($receiverA, 'C'); // 请求者 $invoker = new Invoker(); $invoker->setCommand($commandOne); $invoker->setCommand($commandTwo); $invoker->setCommand($commandThree); $invoker->exec(); $invoker->undo(); // 新加一个单独的执行者,只执行一个命令 $invokerA = new Invoker(); $invokerA->setCommand($commandOne); $invokerA->exec(); // 命令A已经执行了,再次执行全部的命令执行者,A命令的state判断无法生效 $invoker->exec();
Beispiel
Die SMS-Funktion ist zurück, das haben wir gefunden Zusätzlich zum Factory-Modus scheint der Befehlsmodus eine gute Möglichkeit zu sein, dies zu implementieren. Hier verwenden wir immer noch diese SMS- und Push-Schnittstellen. Lassen Sie uns ohne weitere Umschweife eine weitere im Befehlsmodus implementieren. Natürlich können interessierte Freunde dann unsere SMS-Entzugsfunktion implementieren. Überlegen Sie, wie die obige Befehlslöschung implementiert wird.
https://github.com/zhangyue0503/designpatterns-php/blob/master/09.command/source/command-message.php
<?php class SendMsg { private $command = []; public function setCommand(Command $command) { $this->command[] = $command; } public function send($msg) { foreach ($this->command as $command) { $command->execute($msg); } } } abstract class Command { protected $receiver = []; public function setReceiver($receiver) { $this->receiver[] = $receiver; } abstract public function execute($msg); } class SendAliYun extends Command { public function execute($msg) { foreach ($this->receiver as $receiver) { $receiver->action($msg); } } } class SendJiGuang extends Command { public function execute($msg) { foreach ($this->receiver as $receiver) { $receiver->action($msg); } } } class SendAliYunMsg { public function action($msg) { echo '【阿X云短信】发送:' . $msg, PHP_EOL; } } class SendAliYunPush { public function action($msg) { echo '【阿X云推送】发送:' . $msg, PHP_EOL; } } class SendJiGuangMsg { public function action($msg) { echo '【极X短信】发送:' . $msg, PHP_EOL; } } class SendJiGuangPush { public function action($msg) { echo '【极X推送】发送:' . $msg, PHP_EOL; } } $aliMsg = new SendAliYunMsg(); $aliPush = new SendAliYunPush(); $jgMsg = new SendJiGuangMsg(); $jgPush = new SendJiGuangPush(); $sendAliYun = new SendAliYun(); $sendAliYun->setReceiver($aliMsg); $sendAliYun->setReceiver($aliPush); $sendJiGuang = new SendJiGuang(); $sendAliYun->setReceiver($jgMsg); $sendAliYun->setReceiver($jgPush); $sendMsg = new SendMsg(); $sendMsg->setCommand($sendAliYun); $sendMsg->setCommand($sendJiGuang); $sendMsg->send('这次要搞个大活动,快来注册吧!!');
》
- In diesem Beispiel handelt es sich immer noch um einen Multi-Befehls- und Multi-Executor-Modus.
- Sie können dieses Beispiel mit der abstrakten Fabrik vergleichen. Die gleiche Funktion wird mit unterschiedlichen Entwurfsmustern implementiert, es sollte jedoch beachtet werden, dass die abstrakte Fabrik dies hat mehr Es geht darum, Objekte zu erzeugen und Objekte zurückzugeben, und der Befehlsmodus ist eine Verhaltensauswahl
- Wir können sehen, dass sich der Befehlsmodus sehr gut zum Bilden einer Befehlswarteschlange eignet. Mehrere Befehle ermöglichen die Ausführung von Befehlen nacheinander
- Es Ermöglicht der empfangenden Partei zu entscheiden, ob sie die Anfrage ablehnt. Der Empfänger hat als Umsetzer mehr Mitspracherecht. Originaladresse: https://juejin.cn/post/6844903950768930823. Autor: Hardcore Project Manager. Lernempfehlung: „
PHP-Video-Tutorial
Das obige ist der detaillierte Inhalt vonEine eingehende Analyse des Befehlsmusters in PHP. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!