이전 글 "PHP 빌더 패턴 심층 분석"에서 PHP 빌더 패턴에 대해 소개했습니다. 이번 글에서는 PHP 디자인 패턴 중 메모 패턴에 대해 알아보겠습니다.
메모, 이름은 실제로 그 기능을 매우 생생하게 설명합니다. 대표적인 예가 원래 하드디스크 게임을 할 때의 아카이브 기능이다. 직면하게 될 큰 보스가 걱정될 때 일반적으로 진행 아카이브를 먼저 저장합니다. 도전에 실패하면 직접 아카이브를 읽어 BOSS에 도전하기 전의 상태로 복원할 수 있습니다. 그런 다음 잠시 즐겁게 연습하고 돌아와서 큰 BOSS를 해결하면 됩니다. 하지만 만약을 대비해 BOSS에 도전하기 전에 항상 파일을 저장해 두는 것이 좋습니다. 또 다른 예는 프로그래머가 매일 사용하는 코드 관리 도구인 Git 또는 Svn입니다. 각 제출은 아카이브 백업과 같습니다. 새 코드에 문제가 있으면 롤백하고 복구하면 됩니다. 이것들은 모두 메모 모드의 일반적인 응용 프로그램입니다. 이 모드를 함께 살펴보겠습니다.
GoF 정의: 객체의 내부 상태를 캡처하고 캡슐화를 파괴하지 않고 이 상태를 객체 외부에 저장합니다. 이런 방식으로 개체는 나중에 원래 저장된 상태로 복원될 수 있습니다
GoF 클래스 다이어그램:
코드 구현:
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; } }
발신자는 개시자라고도 불릴 수 있습니다. 다양한 상황에서 변경될 수 있는 내부 상태가 있습니다. 이벤트가 발생하면 이 상태를 원래 상태로 복원해야 합니다. 여기에는 메모(보관) 생성을 위한 CreateMemento()와 상태 복원(파일 읽기)을 위한 SetMeneto()가 있습니다.
class Memento { private $state; public function SetState($state) { $this->state = $state; } public function GetState() { return $this->state; } }
메모는 매우 간단하며 상태를 기록하는 데 사용됩니다. 이 상태를 객체 형태로 저장하면 작성자가 쉽게 여러 개의 아카이브를 생성하여 다양한 상태를 기록할 수 있습니다.
class Caretaker { private $memento; public function SetMemento($memento) { $this->memento = $memento; } public function GetMemento() { return $this->memento; } }
매니저 클래스라고도 불리는 담당자가 메모를 저장해 두었다가 필요할 때마다 꺼내서 사용합니다. 저장만 담당하며 메모를 수정할 수는 없습니다. 복잡한 애플리케이션에서는 플레이어가 선택할 수 있도록 여러 아카이브 기록을 선택적으로 표시할 수 있는 게임처럼 목록으로 만들 수 있습니다.
$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();
클라이언트 호출에서 우리의 작성자가 상태를 초기화하고 저장한 다음 인위적으로 상태를 변경했습니다. 이때는 담당자를 통해서만 상태를 복원하시면 됩니다.
전체 코드: https://github.com/zhangyue0503/designpatterns-php/blob/master/17.memento/source/memento.php
Example
전체 소스 코드: 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视频教程》
위 내용은 PHP의 메모 모드에 대해 이야기해 보겠습니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!