Dans l'article précédent "Comprendre le mode prototype en PHP en un seul article" nous avons présenté le mode prototype en PHP. Cet article vous amènera à comprendre le mode commande en PHP.
Mode commande, également connu sous le nom de mode action ou transaction, de nombreux manuels utiliseront les restaurants comme exemple. En tant que clients, nous sommes les donneurs de commande, les serveurs sont les destinataires de cette commande, le menu est la commande elle-même et le chef est l'exécuteur de cette commande.
Alors, que résout ce modèle ? Lorsque vous souhaitez modifier la carte, il suffit d'en informer le serveur et elle le transmettra au chef. Autrement dit, nous avons réussi le découplage entre clients et chefs. C'est le découplage entre les appelants et les exécutants.
Bien sûr, de nombreux modèles de conception peuvent le faire, mais ce que le modèle de commande peut faire, c'est permettre à un récepteur de commandes d'implémenter plusieurs commandes (serveur passant des commandes, obtenir des boissons, servir des plats) ou relayer une commande à plusieurs Realizer (chaud cuisinier de plat, cuisinier de plat froid, chef de plat principal). C’est là que le modèle de commande entre vraiment en jeu ! !
Définition GoF : encapsulez une requête en tant qu'objet, vous permettant de paramétrer les clients avec différentes requêtes ; diagramme
Implémentation du code
class Invoker { public $command; public function __construct($command) { $this->command = $command; } public function exec() { $this->command->execute(); } }
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(); } }
class Receiver { public $name; public function __construct($name) { $this->name = $name; } public function action() { echo $this->name . '命令执行了!', PHP_EOL; } }
// 准备执行者 $receiverA = new Receiver('A'); // 准备命令 $command = new ConcreteCommand($receiverA); // 请求者 $invoker = new Invoker($command); $invoker->exec();
En fait, l'exemple de ce restaurant est très clair. C'est une analyse parfaite du modèle de commande
Qu'en est-il de la promesse que plusieurs commandes peuvent être passées ou données à plusieurs chefs ? Ne vous inquiétez pas, le code suivant nous aide à résoudre ce problème
<?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();
Cette fois, nous avons résolu le problème de plusieurs commandes et de plusieurs chefs à la fois, et avons également résolu le problème de l'annulation d'une mauvaise commande si elle était donnée.On peut voir que le mode commande appellera l'objet de l'opération et saura comment l'implémenter. L'objet de l'opération est découplé
https://github.com/zhangyue0503/designpatterns-php/blob/master/09.command/source/command-up.php
ExempleLa fonction SMS est de retour, nous avons constaté que De plus, en plus du mode usine, le mode commande semble être un bon moyen de l'implémenter. Ici, nous utilisons toujours ces interfaces SMS et push. Sans plus tarder, implémentons-en une autre en utilisant le mode commande. Bien entendu, les amis intéressés peuvent ensuite mettre en œuvre notre fonction de retrait de SMS. Pensez à la manière dont l'annulation de la commande ci-dessus est mise en œuvre.
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('这次要搞个大活动,快来注册吧!!');
Instructions
- Dans cet exemple, il s'agit toujours d'un mode multi-commandes et multi-exécuteurs
- Vous pouvez comparer cet exemple avec la fabrique abstraite. La même fonction est implémentée en utilisant différents modèles de conception, mais il convient de noter que la fabrique abstraite a. plus Il s'agit de produire des objets et de renvoyer des objets, et le mode commande est un choix de comportement
- On voit que le mode commande est très adapté pour former une file d'attente de commandes plusieurs commandes permettent d'exécuter les commandes une par une
- . Il permet à la partie destinataire de décider de refuser la demande, le destinataire a plus son mot à dire que l'exécutant
Adresse originale : https://juejin.cn/post/6844903950768930823
Auteur : Chef de projet hardcore
Apprentissage recommandé : "Tutoriel vidéo PHP》
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!