Memento code examples of PHP design patterns (25)

Time:2020-11-26

objective

It provides recovery to the previous state (using rollback) or getting the internal state of the object without breaking the encapsulation (the object does not need to have a function that returns the current state).

The memo pattern is implemented using three classes: originator, caretaker, and memento.

Memento — responsible for storing the unique internal state of the originator, which can contain: string, number, array, instance of class, etc. Memento “is not a public class” (no one should and cannot change it), and prevents objects other than the originator from accessing it. It provides two interfaces: caretaker can only see the narrow interface of memos, and can only pass memos to other objects. The originator, on the other hand, sees a wide interface to the memo, allowing it to access all the data needed to return to the previous state.

Originator — it is responsible for creating memento, recording the current state of external objects, and can use memento to restore internal state. The originator can decide which internal states memento stores the originator as needed. The originator may (should not) have its own methods. However, they cannot change the current state of the saved object.

Caretaker — responsible for keeping memento. It can modify an object, determine the current state of the object in the originator at the current time, obtain the current state of the object from the originator, or roll back the state of the object in the originator.

example

  • Control state in ORM model before saving

  • The random number is stored in the sequential machine

  • Send a random number

UML diagram

The official PHP advanced learning exchange community “click” manages and sorts out some materials. Bat and other first-line factories have advanced knowledge systems (related learning materials and written test questions) and are not limited to: distributed architecture, high scalability, high performance, high concurrency, server performance tuning, tp6, laravel, yii2, redis, swote, soft, Kafka, MySQL optimization, shell script, dock Er, micro service, nginx and other knowledge points

code

  • Memento.php
state = $stateToSave;
    }

    /**
     * @return State
     */
    public function getState()
    {
        return $this->state;
    }
}
  • State.php
state = $state;
    }

    private static function ensureIsValidState(string $state)
    {
        if (!in_array($state, self::$validStates)) {
            throw new \InvalidArgumentException('Invalid state given');
        }
    }

    public function __toString(): string
    {
        return $this->state;
    }
}
  • Ticket.php
currentState = new State(State::STATE_CREATED);
    }

    public function open()
    {
        $this->currentState = new State(State::STATE_OPENED);
    }

    public function assign()
    {
        $this->currentState = new State(State::STATE_ASSIGNED);
    }

    public function close()
    {
        $this->currentState = new State(State::STATE_CLOSED);
    }

    public function saveToMemento(): Memento
    {
        return new Memento(clone $this->currentState);
    }

    public function restoreFromMemento(Memento $memento)
    {
        $this->currentState = $memento->getState();
    }

    public function getState(): State
    {
        return $this->currentState;
    }
}

test

  • Tests/MementoTest.php
open();
        $openedState = $ticket->getState();
        $this->assertEquals(State::STATE_OPENED, (string) $ticket->getState());

        $memento = $ticket->saveToMemento();

        //Assign ticket
        $ticket->assign();
        $this->assertEquals(State::STATE_ASSIGNED, (string) $ticket->getState());

        //You are now restored to the open state, but you need to verify that the current state has been cloned as a replica
        $ticket->restoreFromMemento($memento);

        $this->assertEquals(State::STATE_OPENED, (string) $ticket->getState());
        $this->assertNotSame($openedState, $ticket->getState());
    }
}

PHP Internet architect’s way to grow * “design patterns” Ultimate Guide

PHP Internet architect 50K growth Guide + general outline of industry problem solving (continuously updated)

Interview 10 companies, get 9 offers, PHP interview questions in 2020

If you like my article and want to communicate and learn with more senior developers, you can get more technical advice and guidance related to interview with large factories. Welcome to join our group, code: phpzh (junyang number: 856460874).

The latest PHP advanced tutorial 2020, full series!

If the content is good, I hope you can support and encourage you to click like / like, and you are welcome to exchange views. In addition, if you have any questions, you can suggest the content you want to see in the comments