Home > Article > Backend Development > A brief analysis of the memo pattern
During the application design process, some specific operations need to be able to support undo, such as a file management system I was writing recently. Some basic file operations, such as rename, copy, cut, etc., need to support undo and redo operations to provide a better user experience. As we all know, undo and redo operations require two modes to support: memento mode (memento) saves the object operation data status, and command mode (command) encapsulates user requests. Combined they provide good undo and redo operations. For command mode, you can refer to the above article and click to open the link. The following mainly talks about the implementation of memo mode. If there are any errors, please let me know.
There are three main participants in the memo mode:
a. Memento object (Memento) that saves status information
b. Originator (Originator) that generates status information
c. Manager of memo object (CareTaker)
The originator provides two external interfaces:
create_memento(); //保存对象状态信息创建一个备忘录返回 set_memento(Memento $mem); //根据传入的备忘录获取状态信息,恢复状态
set_state(State $state); //设备备忘录当前状态 get_state(); //获取备忘录当前状态Memo object implementation:
class Memento { private $state; public function get_state(){ return $this->state; } public function set_state(State $state){ $this->state = clone $state; } }The set_state interface ensures the uniqueness of parameter types through State parameter prompts. It should be noted that PHP does not execute the copy constructor like C++ when assigning objects by default. PHP is based on a reference object counter, and the default counter of object assignment is incremented by one. Here we use the clone operation provided by PHP to ensure that we get a brand new object.
Originator implementation:
class Originator{ private $state; function _construct(){ $this->state = new State(); $this->state->set('action', 'create originator'); } function do_action1(){ $this->state->set('action', 'do_action 1'); } function do_action2(){ $this->state->set('action', 'do_action 2'); } function create_memento(){ $mem = new Memento(); $men->set_state($this->state); return $mem; } function set_memento(Memento $mem){ $this->state = $mem->get_state(); } function dump(){ echo $this->state->get('action') . "\n"; } }
class State{ private $values = array(); public function set($key, $value){ $this->values[$key] = $value; } public function get($key){ if(isset($this->values[$key])){ return $this->values[$key]; } return null; } }Finally, a simple implementation of the memo manager:
class CareTaker{ private $command; function __construct($cmd="Originator1"){ $this->command = $cmd; } private function do_execute(){ switch($this->command){ case 'Originator1':{ $action = new Originator(); $mem1 = $action->create_memento(); $action->dump(); $action->do_action1(); $mem2 = $action->create_memento(); $action->dump(); $action->do_action2(); $mem3 = $action->create_memento(); $action->dump(); //状态恢复 $action->set_memento($mem2); $action->dump(); $action->set_memento($mem1); $action->dump(); } } } }
The end.
The above has introduced a brief analysis of the memo mode, including various aspects. I hope it will be helpful to friends who are interested in PHP tutorials.