PHP의 메모 모드에 대해 이야기해 보겠습니다.

青灯夜游
풀어 주다: 2023-04-10 11:40:02
앞으로
2198명이 탐색했습니다.

이전 글 "PHP 빌더 패턴 심층 분석"에서 PHP 빌더 패턴에 대해 소개했습니다. 이번 글에서는 PHP 디자인 패턴 중 메모 패턴에 대해 알아보겠습니다.

PHP의 메모 모드에 대해 이야기해 보겠습니다.

메모, 이름은 실제로 그 기능을 매우 생생하게 설명합니다. 대표적인 예가 원래 하드디스크 게임을 할 때의 아카이브 기능이다. 직면하게 될 큰 보스가 걱정될 때 일반적으로 진행 아카이브를 먼저 저장합니다. 도전에 실패하면 직접 아카이브를 읽어 BOSS에 도전하기 전의 상태로 복원할 수 있습니다. 그런 다음 잠시 즐겁게 연습하고 돌아와서 큰 BOSS를 해결하면 됩니다. 하지만 만약을 대비해 BOSS에 도전하기 전에 항상 파일을 저장해 두는 것이 좋습니다. 또 다른 예는 프로그래머가 매일 사용하는 코드 관리 도구인 Git 또는 Svn입니다. 각 제출은 아카이브 백업과 같습니다. 새 코드에 문제가 있으면 롤백하고 복구하면 됩니다. 이것들은 모두 메모 모드의 일반적인 응용 프로그램입니다. 이 모드를 함께 살펴보겠습니다.

Gof 클래스 다이어그램 및 설명

GoF 정의: 객체의 내부 상태를 캡처하고 캡슐화를 파괴하지 않고 이 상태를 객체 외부에 저장합니다. 이런 방식으로 개체는 나중에 원래 저장된 상태로 복원될 수 있습니다

GoF 클래스 다이어그램:

PHP의 메모 모드에 대해 이야기해 보겠습니다.

코드 구현:

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();
로그인 후 복사

클라이언트 호출에서 우리의 작성자가 상태를 초기화하고 저장한 다음 인위적으로 상태를 변경했습니다. 이때는 담당자를 통해서만 상태를 복원하시면 됩니다.

  • 직접 말하면 메모 모드는 외부 클래스 B가 A의 내부 상태를 저장한 후 적절한 시점에 이 상태를 쉽게 복원하도록 하는 것입니다.
  • 브라우저 롤백, 데이터베이스 백업 및 복원, 운영 체제 백업 및 복원, 문서 실행 취소 및 다시 실행, 체스 및 카드 게임 후회 등 실제로 메모 모드에 대한 많은 응용 시나리오가 있습니다.
  • 이 모드는 원본을 유지할 수 있습니다. 서버 캡슐화, 즉 이러한 상태는 외부 개체로부터 숨겨야 하므로 메모 개체에만 전달하여 기록할 수 있습니다.
  • 발신자와 메모 간의 상태 복사는 성능 문제, 특히 대형 개체 컴퓨터의 내부 상태로 인해 특정 상태가 누락되는 등 일부 코딩 허점이 발생할 수도 있습니다. 컴퓨터를 특정 시점의 상태로 복원할 수 있는 Mac의 타임머신 기능에 대해 들어보신 적이 있습니까? 실제로 Windows 고스트에도 비슷한 기능이 있습니다. 우리의 모바일 운영체제 역시 그러한 기능을 개발하기로 결정했습니다. Time Machine 백업을 클릭하면 휴대폰의 모든 정보, 데이터 및 상태 정보가 압축되어 저장됩니다. 사용자가 허용하면 압축된 패키지를 클라우드 서버에 업로드하여 사용자의 휴대폰 메모리를 차지하지 않습니다. , 사용자의 휴대폰 메모리에만 저장이 가능합니다. 사용자의 휴대폰을 특정 시점으로 복원해야 할 경우 모든 타임머신 백업 목록을 표시합니다. 사용자는 단 한 번의 클릭만으로 휴대폰 시스템 상태를 당시의 상태로 복원할 수 있습니다. 별로 편리하지 않아요! !

전체 코드: https://github.com/zhangyue0503/designpatterns-php/blob/master/17.memento/source/memento.php

Example

이번에는 문자 메시지로 돌아왔습니다. 예. 일반적으로 SMS 또는 이메일 전송 기능을 수행할 때 데이터베이스나 캐시에서 전송할 콘텐츠를 읽고 전송하는 대기열이 있습니다. 성공하면 SMS 상태가 무시됩니다. 실패 또는 재전송으로 변경됩니다. 여기서는 이전의 전송되지 않은 상태로 직접 변경한 후 다음 전송 큐가 다시 전송을 수행할 때까지 기다립니다.

SMS 전송 클래스 다이어그램

전체 소스 코드: https://github.com/zhangyue0503/designpatterns-php/blob/master/17.memento/source/memento-message.phpPHP의 메모 모드에 대해 이야기해 보겠습니다.

<?php
class Message
{
    private $content;
    private $to;
    private $state;
    private $time;

    public function __construct($to, $content)
    {
        $this->to = $to;
        $this->content = $content;
        $this->state = &#39;未发送&#39;;
        $this->time = time();
    }

    public function Show()
    {
        echo $this->to, &#39;---&#39;, $this->content, &#39;---&#39;, $this->time, &#39;---&#39;, $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(&#39;手机号&#39; . $i, &#39;内容&#39; . $i);
    echo &#39;初始状态:&#39;;
    $m->Show();

    // 保存初始信息
    $sc = new StateContainer();
    $sc->SetSaveState($m->CreateSaveSate());
    $scList[] = $sc;

    // 模拟短信发送,2发送成功,3发送失败
    $pushState = mt_rand(2, 3);
    $m->SetState($pushState == 2 ? &#39;发送成功&#39; : &#39;发送失败&#39;);
    echo &#39;发布后状态:&#39;;
    $m->Show();

    $mList[] = $m;
}

// 模拟另一个线程查找发送失败的并把它们还原到未发送状态
sleep(2);
foreach ($mList as $k => $m) {
    if ($m->GetState() == &#39;发送失败&#39;) { // 如果是发送失败的,还原状态
        $m->SetSaveState($scList[$k]->GetSaveState());
    }
    echo &#39;查询发布失败后状态:&#39;;
    $m->Show();
}
로그인 후 복사

说明

  • 短信类做为我们的原发器,在发送前就保存了当前的发送状态
  • 随机模拟短信发送,只有两个状态,发送成功或者失败,并改变原发器的状态为成功或者失败
  • 模拟另一个线程或者脚本对短信的发送状态进行检查,如果发现有失败的,就将它重新改回未发送的状态
  • 这里我们只是保存了发送状态这一个字段,其他原发器的内部属性并没有保存
  • 真实的场景下我们应该会有一个重试次数的限制,当超过这个次数后,状态改为彻底的发送失败,不再进行重试了

原文地址:https://juejin.cn/post/6844903983555805192

作者:硬核项目经理

推荐学习:《PHP视频教程

위 내용은 PHP의 메모 모드에 대해 이야기해 보겠습니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:juejin.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿