本文同步更新於blog
情境:让我们利用备忘录模式,实作一个仿真Git
<?php
namespace App\MementoPattern\Git;
/**
* This is our Memento in memento pattern
*/
class Commit
{
/**
* This is our state.
*
* @var string
*/
private $code;
public function __construct(string $code)
{
$this->code = $code;
}
public function getCode(): string
{
return $this->code;
}
}
Commit属於备忘录类别 (Memento),
负责储存 原始类别 (Originator) 的状态。
在这个范例中,code就是我们的状态。
<?php
namespace App\MementoPattern\Git;
use App\MementoPattern\Git\Commit;
/**
* This is our CareTaker in memento pattern
*/
class Folder
{
/**
* @var Commit[]
*/
private $commits = [];
/**
* @param Commit $commit
*/
public function saveCommit(Commit $commit)
{
$this->commits[] = $commit;
}
/**
* @param int $previous
* @return Commit
*/
public function getPreviousCommit(int $previous): Commit
{
$commitAmount = count($this->commits);
$index = $commitAmount - $previous;
$result = $this->commits[$index];
return $result;
}
}
Folder属於管理类别 (Caretaker),
负责管理Commit的存储。
<?php
namespace App\MementoPattern\Git;
use App\MementoPattern\Git\Commit;
use App\MementoPattern\Git\Folder;
/**
* This is our Originator in memento pattern
*/
class Git
{
/**
* @var Folder
*/
protected $folder;
/**
* This is our state.
*
* @var string
*/
private $code;
/**
* @param Folder $folder
*/
public function __construct(Folder $folder)
{
$this->folder = $folder;
}
/**
* Getter
*
* @return string
*/
public function getUntrackedCode(): string
{
return $this->code;
}
/**
* Setter
*
* @var string
*/
public function writeCode(string $code)
{
$this->code = $code;
}
public function commit()
{
$commit = $this->createCommit();
$this->code = '';
$this->folder->saveCommit($commit);
}
private function createCommit(): Commit
{
return new Commit($this->code);
}
/**
* @param int $previous
* @return string
*/
public function reset(int $previous): string
{
return $this->code = $this->folder->getPreviousCommit($previous)->getCode();
}
}
Git属於我们的原始类别 (Originator),具有code状态。
getUntrackedCode()及writeCode()是我们code状态的Getter/Setter。
透过commit()方法,生成Commit,保存了当下code的状态,
并传给Folder作为纪录存档。
透过reset()方法,我们可以载入先前存档好的code状态。
<?php
namespace App\MementoPattern\Git;
use App\MementoPattern\Git\Folder;
use App\MementoPattern\Git\Git;
class Program
{
public function run()
{
$folder = new Folder();
$git = new Git($folder);
$git->writeCode('aaa');
dump($git->getUntrackedCode()); //aaa
$git->commit();
dump($git->getUntrackedCode()); //''
$git->writeCode('bbb');
$git->commit();
$git->reset(1);
dump($git->getUntrackedCode()); //aaa
}
}
[单一职责原则]
我们将原始类别、备忘录类别与管理类别视为三种职责。
[开放封闭原则]
透过备忘录类别与管理类别,
原始类别不需要实作恢复状态的相关功能。
最後附上类别图:
(注:若不熟悉 UML 类别图,可参考UML类别图说明。)
ʕ •ᴥ•ʔ:这个范例只是利用Git作为媒介,与真实Git行为不完全相同。
>>: Dashboard制作教学:做一张互动式仪表板,只需要5步!超简单~
媒体协商 上一篇提到,要进行 WebRTC的连线需要处理以下两个问题,今天我们就来看看媒体协商的部分...
如果想印出1到100的数字,更常的做法是使用for回圈而不是while 例 for i in 1.....
当我们熟建立了关键字的基本概念後,那不妨开始在 Google Ads 建立完善的广告活动吧,并透过一...
转换操作符 map/mapError map操作符会执行给定的闭包,将上游发布的内容进行转换,然後再...
虽然今天已经是最後一天,但如果明天系统仍然可以发文的话,会先继续发文,方便之後回顾整理系列文时,能够...