In the previous article "In-depth analysis of the builder pattern in PHP" we introduced the builder pattern in PHP. The following article will take you to understand the memo pattern in PHP design pattern. .
Memo, this name actually explains its function very vividly. A typical example is the archive function when we originally played hard disk games. When you are worried about the big BOSS you are about to face, you usually save a progress archive first. If the challenge fails, you can directly read the archive to restore to the state before challenging the BOSS. Then you can happily practice for a while and come back to solve the big BOSS. However, just in case, it's always a good idea to save a file before challenging the BOSS. Another example is Git or Svn, the code management tools that we programmers use every day. Each submission is like an archive backup. When there is a problem with the new code, just roll back and recover. These are all typical applications of the memo mode. Let’s take a look at this mode together.
GoF definition: Capture the internal state of an object without destroying encapsulation, and Save this state outside of this object. In this way, the object can be restored to its original saved state
GoF class diagram:
Code implementation:
class Originator { private $state; public function SetMeneto(Memento $m) { $this->state = $m->GetState(); } public function CreateMemento() { $m = new Memento(); $m->SetState($this->state); return $m; } public function SetState($state) { $this->state = $state; } public function ShowState() { echo $this->state, PHP_EOL; } }
The originator can also be called the initiator. It has an internal state that can change under different circumstances. When an event occurs, this state needs to be restored to its original state. Here, we have a CreateMemento() for creating a memo (archive) and a SetMeneto() for restoring the state (reading the file).
class Memento { private $state; public function SetState($state) { $this->state = $state; } public function GetState() { return $this->state; } }
Memo, very simple, is used to record status. Saving this state in the form of an object allows the originator to easily create many archives to record various states.
class Caretaker { private $memento; public function SetMemento($memento) { $this->memento = $memento; } public function GetMemento() { return $this->memento; } }
The person in charge, also called the manager class, saves the memo and takes out the memo from here when needed. It is only responsible for saving and cannot modify the memo. In complex applications, this can be made into a list, just like a game that can selectively display multiple archive records for players to choose from.
$o = new Originator(); $o->SetState('状态1'); $o->ShowState(); // 保存状态 $c = new Caretaker(); $c->SetMemento($o->CreateMemento()); $o->SetState('状态2'); $o->ShowState(); // 还原状态 $o->SetMeneto($c->GetMemento()); $o->ShowState();
In the client call, our originator initialized the state and saved it, and then artificially changed the state. At this time, you only need to restore the status through the person in charge.
Mac's time machine function Everyone knows that you can restore your computer to a state at a certain point in time. In fact, Windows ghost also has a similar function. Our mobile operating system also decided to develop such a function. When we click Time Machine Backup, all the information, data, and status information on the phone will be compressed and saved. If the user allows it, we will upload the compressed package to our cloud server to avoid occupying the user's phone memory. Otherwise, it will It can only be saved to the user's mobile phone memory. When the user's mobile phone needs to be restored to a certain point in time, we will list all the time machine backups. The user can restore the mobile phone system status to what it was at that time with just a tap of a finger. Isn't it very convenient! !
Full code: https://github.com/zhangyue0503/designpatterns-php/blob/master/17.memento/source/memento.php
This time we return to the example of sending text messages. Usually when we do SMS or email sending functions, there will be a queue that reads the content to be sent from the database or cache and sends it. If it succeeds, it will be ignored. If it fails, the status of the SMS will be changed to failed or resent. . Here, we directly change it back to the previous unsent state and then wait for the next sending queue to perform sending again.
SMS sending class diagram
Full source code: https://github.com/zhangyue0503/designpatterns-php /blob/master/17.memento/source/memento-message.php
<?php class Message { private $content; private $to; private $state; private $time; public function __construct($to, $content) { $this->to = $to; $this->content = $content; $this->state = '未发送'; $this->time = time(); } public function Show() { echo $this->to, '---', $this->content, '---', $this->time, '---', $this->state, PHP_EOL; } public function CreateSaveSate() { $ss = new SaveState(); $ss->SetState($this->state); return $ss; } public function SetSaveState($ss) { if ($this->state != $ss->GetState()) { $this->time = time(); } $this->state = $ss->GetState(); } public function SetState($state) { $this->state = $state; } public function GetState() { return $this->state; } } class SaveState { private $state; public function SetState($state) { $this->state = $state; } public function GetState() { return $this->state; } } class StateContainer { private $ss; public function SetSaveState($ss) { $this->ss = $ss; } public function GetSaveState() { return $this->ss; } } // 模拟短信发送 $mList = []; $scList = []; for ($i = 0; $i < 10; $i++) { $m = new Message('手机号' . $i, '内容' . $i); echo '初始状态:'; $m->Show(); // 保存初始信息 $sc = new StateContainer(); $sc->SetSaveState($m->CreateSaveSate()); $scList[] = $sc; // 模拟短信发送,2发送成功,3发送失败 $pushState = mt_rand(2, 3); $m->SetState($pushState == 2 ? '发送成功' : '发送失败'); echo '发布后状态:'; $m->Show(); $mList[] = $m; } // 模拟另一个线程查找发送失败的并把它们还原到未发送状态 sleep(2); foreach ($mList as $k => $m) { if ($m->GetState() == '发送失败') { // 如果是发送失败的,还原状态 $m->SetSaveState($scList[$k]->GetSaveState()); } echo '查询发布失败后状态:'; $m->Show(); }
说明
原文地址:https://juejin.cn/post/6844903983555805192
作者:硬核项目经理
推荐学习:《PHP视频教程》
The above is the detailed content of Let's talk about the memo mode in PHP. For more information, please follow other related articles on the PHP Chinese website!