Home  >  Article  >  Backend Development  >  A brief analysis of the memo pattern

A brief analysis of the memo pattern

WBOY
WBOYOriginal
2016-08-08 09:32:39961browse

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); //根据传入的备忘录获取状态信息,恢复状态   

The memo object provides two interfaces:
    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";
        }
    }

Status information object:
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();
                    }
                }         
        }
    }

There are several areas that can be improved. First, the manager should provide a queue to manage a series of memo objects. Secondly, the client request command is distributed using a big switch-case instead of using the command mode to encapsulate the request as an object, which leads to a confusing class structure. The next article will implement a complete version of the undo-redo operation.

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.

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn