php 和设计模式 - 备忘录模式
发表于|更新于|设计模式
|总字数:194|阅读时长:1分钟|浏览量:
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存该对象的内部状态。这样就可以方便的恢复到之前保存的状态。
1 | class Memento |
好了,以上就是一个简易版的备忘录模式了,还是比较好理解的。
文章作者: m-finder
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 M-finder!
相关推荐

2021-03-21
php 和设计模式 - 命令行模式
用过 laravel 框架的应该都知道,其脚本模块非常强大,这些脚本,也就是命令行模式。 说到命令行,就不得步提一下 cli 和 cgi 的区别,在 nginx 中,php 并不是直接执行的,而是通过 cgi 调用 php 并获取执行结果。 而 cli 就是命令行接口,主要用于 shell 脚本的开发。 123456789php command.php/opt/homebrew/var/www/design-patternphp-cli command.phpX-Powered-By: PHP/7.4.16Content-type: text/html; charset=UTF-8/opt/homebrew/var/www/design-pattern 不多说了,回头再专门看一下这方面的东西。

2021-03-21
php 和设计模式 - 生成器模式
生成器模式也叫建造者模式,主要用于将一个复杂对象的构造与它的表示分离。该模式允许你使用相同的代码生成不同类型和形式的对象。 什么是复杂对象呢?举个🌰,人类,都有个脑袋,有个身体,又有两条胳膊腿儿,那么,我们就可以把人看作是一个复杂对象。 那么,对于生成器模式来说,我们要把人类对象的创建与它的实例表示进行分离。 class Human { public function setHead(string $head) { echo 'head:', $head, PHP_EOL; } public function setBody(string $body) { echo 'body:', $body, PHP_EOL; } public function setArms(string $leftArm, string $rightArm) { echo 'left arm:', $leftArm, ' right arm:', $rightArm, PHP_EOL; } } interface Builder { public function buildHead(); public function buildBody(); public function buildArms(); public function getResult(): Human; } class HumanBuilder implements Builder{ private Human $human; public function __construct() { $this->human = new Human(); } public function buildHead() { $this->human->setHead('ai'); } public function buildBody() { $this->human->setBody('body'); } public function buildArms() { $this->human->setArms('left', 'right'); } public function getResult(): Human { return $this->human; } } class Director{ public function builder(Builder $builder): Human { $builder->buildHead(); $builder->buildBody(); $builder->buildArms(); return $builder->getResult(); } } $director = new Director(); $human = $director->builder(new HumanBuilder()); 好了,生成器模式到此结束。

2021-03-21
php 和设计模式 - 依赖注入模式
依赖注入是控制反转的一种实现方式。要实现控制反转,需要将创建被调用者实例的工作交由 IOC 容器完成,然后在调用者中注入被调用者,通常使用构造器或方法注入实现。这样我们舅实现了调用者和被调用者的解偶,这个过程就是依赖注入。 那么控制反转是什么呢?其实也就是 A 依赖于 B,常规做法是在 A 中直接实例化 B,那么控制反转就是将 B 在外部实例化,然后传入 A 去使用。看完以后,其实对依赖注入也就有了理解。 12345678910111213141516171819202122232425262728class Computer{ protected HardDisk $hardDisk; public function __construct(HardDisk $disk) { $this->hardDisk = $disk; } public function run() { $this->hardDisk->run(); echo '一台没有感情的电脑开始运行', PHP_EOL; }}class HardDisk{ public function run() { echo '一块没有感情的硬盘开始运行', PHP_EOL; }}$disk = new HardDisk();$computer = new Computer($disk);$computer->run(); 以上代码就是一个简单的依赖注入,你以为这就结束了?并没有,咱们在学一下 IOC 容器: 1234567891011121314151617181920212223242526272829class Container{ public array $bindings = []; public function bind($key, Closure $value) { $this->bindings[$key] = $value; } public function make($key) { $new = $this->bindings[$key]; return $new(); }}$container = new Container();$container->bind('disk', function (){ return new HardDisk();});$container->bind('computer', function () use($container){ return new Computer($container->make('disk'));});$computer = $container->make('computer');$computer->run(); ok,以上就是依赖注入的全部代码了。

2021-03-21
php 和设计模式 - 策略模式
定义一组算法,把它们一个个封装起来,并使它们能够快速切换。本模式使得算法可以独立于使用它的客户而变化。一般用于避免多重条件判断和在运行时进行更改。 123456789101112131415161718192021222324252627282930313233343536373839404142434445interface Strategy{ public function algorithm();}class AlgorithmA implements Strategy{ public function algorithm() { echo '算法 A', PHP_EOL; }}class AlgorithmB implements Strategy{ public function algorithm() { echo '算法 B', PHP_EOL; }}class Context{ protected Strategy $strategy; public function __construct(Strategy $strategy) { $this->strategy = $strategy; } public function callAlgorithm() { $this->strategy->algorithm(); }}$algorithmA = new AlgorithmA();$contextA = new Context($algorithmA);$contextA->callAlgorithm();$algorithmB = new AlgorithmB();$contextB = new Context($algorithmB);$contextB->callAlgorithm(); 跟工厂模式非常相似,但是策略模式属于行为型模式,并不会返回一个具体的对象,而是强调其行为。通过调用上下文将要调用的方法封装起来,客户端只要调用上下文的方法就可以了。 那么,跟工厂结合一下是不是更好呢?

2021-03-21
php 和设计模式 - 工厂模式
工厂模式工厂模式是一种类,它具有为你创建对象的某些方法,你可以通过工厂创建对象,而不是直接 new,这样当你需要替换创建的对象类型时,只需要修改工厂即可。 根据抽象程度不同,工厂模式又分为简单工厂、工厂方法和抽象工厂三种。 简单工厂简单工厂与静态工厂的唯一区别是有没有使用静态方法生成实例,因此这里不再将其分为两种模式。 123456789101112131415161718192021222324252627282930313233343536373839404142interface Car{ public function makeCar();}class BMWCar implements Car{ public function makeCar() { echo '来一辆别摸我', PHP_EOL; }}class VolvoCar implements Car{ public function makeCar() { echo '来一辆沃尔沃', PHP_EOL; }}class Factory{ public static function createBMW(): BMWCar { return new BMWCar(); } public static function createVolvo(): VolvoCar { return new VolvoCar(); }}$bmw = Factory::createBMW();$bmw->makeCar();$volvo = Factory::createVolvo();$volvo->makeCar(); 实现比较简单,但是当我们要新增一种车🚗时,就必须修改工厂,这在一定程度上违反了开闭原则。所以严格意义上简单工厂不属于 23 种设计模式。 工厂方法工厂方法是针对每一种产品提供一个工厂类,通过不同的工厂实例来创建不同的产品实例。解决了简单工厂新增具体实现需要修改工厂的问题,支持增加任意同一种抽象产品,不修改原有工厂。 那么,把刚才的简单工厂改造一下吧: 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253interface Car{ public function makeCar();}class BMWCar implements Car{ public function makeCar() { echo '来一辆别摸我', PHP_EOL; }}class VolvoCar implements Car{ public function makeCar() { echo '来一辆沃尔沃', PHP_EOL; }}interface Factory{ public static function getInstance(): Car;}class BMwFactory implements Factory{ /** * @return BMWCar */ public static function getInstance(): Car { return new BMWCar(); }}class VolvoFactory implements Factory{ public static function getInstance(): Car { return new VolvoCar(); }}$bmw = BMwFactory::getInstance();$bmw->makeCar();$volvo = VolvoFactory::getInstance();$volvo->makeCar(); 不同的工厂生产不同的产品,新增产品类型时,只需要新建一个工厂即可,不再需要改动原有工厂,符合了开闭原则。 抽象工厂抽象工厂与工厂方法的区别是,抽象工厂用于生产一系列产品,工厂方法只生产一个产品,会产生大量的工厂类。 宝马生产跑车、轿车还有 mini,宝马是一个产品族,跑车、轿车等是产品的等级。那么,也就是说一个工厂,可以生产相同品牌的不同产品。 那就不写🌰了吧。懒。 总结简单工厂增加产品不方便。工厂方法增加产品很方便,但是会产生大量的工厂类。抽象工厂可以生产多个产品,但是新增产品也需要修改工厂。

2021-03-21
php 和设计模式 - 中介者模式
最近太忙,拖更好多天,难受…… 废话不多说,先来看看概念:用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地互相引用,从而使其耦合松散,而且可以肚里地改变它们之间的交互。 也就相当于你租了个房子,但是房东常年旅居国外,有事情你也不需要找房东,因为房东把所有事情都委托给了中介。 令人羡慕的房东啊…… 举个🌰: 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990<?php// 中介者模式interface MediatorInterface{ public function send($service, string $message);}class Mediator implements MediatorInterface{ public function send($service, string $message) { $service->notify($message); }}abstract class Colleague{ private MediatorInterface $mediator; protected Colleague $colleague; public function setColleague(Colleague $colleague) { $this->colleague = $colleague; } public function getColleague(): Colleague { return $this->colleague; } public function setMediator(MediatorInterface $mediator) { $this->mediator = $mediator; } public function getMediator(): MediatorInterface { return $this->mediator; } public abstract function notify(string $message);}class ClientA extends Colleague{ public function send($message) { return $this->getMediator()->send($this, $message); } public function notify(string $message) { echo get_class($this->getColleague()), ' 收到消息:', $message, PHP_EOL; }}class ClientB extends Colleague{ public function send($message) { return $this->getMediator()->send($this, $message); } public function notify(string $message) { echo get_class($this->getColleague()), ' 收到消息:', $message, PHP_EOL; }}$mediator = new Mediator();$clientA = new ClientA();$clientB = new ClientB();$clientA->setMediator($mediator);$clientB->setMediator($mediator);$clientA->setColleague($clientB);$clientB->setColleague($clientA);$clientA->send('吃饭了没?');$clientB->send('没呢,要请客?'); 这个模式比较适用于通讯类产品,聊天啊、直播什么的,可以实现用户与用户之间的结偶,不需要让一个用户去维护所有管理的用户对象,但是同时也存在一些问题,比如当业务逻辑更加复杂时,中介类就会更加复杂和庞大,所以应用的同时也要考虑该如何取舍。 ok,以上就是终结者模式了,代码还是比较通透的。