23种设计模式合集,只看这一篇就够了
目录
- 1、单例模式
- 2、简单工厂模式
- 3、工厂方法模式
- 4、抽象工厂模式
- 5、装饰器模式
- 6、适配器模式
- 7、观察者模式
- 8、迭代器模式
- 9、原型模式
- 10、命令模式
- 11、策略模式
- 12、责任链模式
- 13、代理模式
- 14、享元模式
- 15、组合模式
- 16、中介者模式
- 17、建造者模式
- 18、备忘录模式
- 19、桥接模式
- 20、门面模式
- 21、模板方法模式
- 22、状态模式
- 23、访问者模式
- 24、注册树模式
1、单例模式
单例模式特点是三私一公
- 私有的静态属性 用于存放实例
- 私有的构造方法 防止在类的外部创建实例对象
- 私有的克隆方法 防止在类的外部克隆对象
- 公有的静态方法 对外界提供实例对象
举例:程序应用中涉及到数据库操作时,如果每次操作都连接数据库就会带来大量的资源消耗,此时可以使用单例模式来创建唯一的数据库连接对象。
下面直接 上代码
。
class Singleton{ private static $_instance; private function __construct() { // 单例操作 } private function __clone(){} public static function getInstance() { // 判断某一变量 是否是某个类的实例 防止创建多个对象 if (!self::$_instance instanceof Singleton) { self::$_instance = new Singleton(); } return self::$_instance; } public function save() { return '业务逻辑' . PHP_EOL; }}// 测试$singleton = Singleton::getInstance();echo $singleton->save();$singletonB = Singleton::getInstance();if ($singleton === $singletonB) { echo '是相同的对象';}
运行结果:
2、简单工厂模式
描述:传递不同的参数 可以返回不同的实例对象
将调用对象与创建对象分离,调用者直接向工厂请求,减少代码耦合,提高系统的可维护性与可扩展性。
下面直接 上代码
。
// 工厂类class Factory{ public static function createProduct(string $type): Product { $product = null; switch ($type) { case 'A': $product = new ProductA(); break; case 'B': $product = new ProductB(); break; } return $product; }}// 产品接口和实现interface Product{ public function show();}class ProductA implements Product{ public function show() { echo '我是商品A'; }}class ProductB implements Product{ public function show() { echo '我是商品B'; }}// 测试$productA = Factory::createProduct('A');$productB = Factory::createProduct('B');$productA->show();$productB->show();
运行结果:
3、工厂方法模式
描述:在子类中实现父类的抽象方法
不需要修改工厂类,只需要添加就行。符合开闭原则
下面直接 上代码
。
// 商品接口的实现类interface Product2{ function show(): void;}class ConcreateProductA implements Product2{ public function show(): void { echo '我是商品A', PHP_EOL; }}class ConcreateProductB implements Product2{ public function show(): void { echo '我是商品B', PHP_EOL; }}// 工厂的抽象类与创建类abstract class Creator{ // 抽象工厂方法 abstract protected function FactoryMethod(): Product2; // 操作方法 public function AnOperation(): Product2 { return $this->FactoryMethod(); }}class ConcreateCreatorA extends Creator{ // 实现操作方法 protected function FactoryMethod(): Product2 { return new ConcreateProductA(); }}class ConcreateCreatorB extends Creator{ protected function FactoryMethod(): Product2 { return new ConcreateProductB(); }}// 测试$factoryA = new ConcreateCreatorA();$factoryB = new ConcreateCreatorB();$factoryA->AnOperation()->show();$factoryB->AnOperation()->show();
运行结果:
4、抽象工厂模式
描述:不写了 自己感悟吧
下面直接 上代码
。
// 商品A的抽象接口interface AbstractProductA{ public function show(): void;}// 商品A1的实现class ProductA1 implements AbstractProductA{ public function show(): void { echo '我是商品A1', PHP_EOL; }}// 商品A2的实现class ProductA2 implements AbstractProductA{ public function show(): void { echo '我是商品A2', PHP_EOL; }}// 商品B的抽象接口interface AbstractProductB{ public function show(): void;}// 商品B1的实现class ProductB1 implements AbstractProductB{ public function show(): void { echo '我是商品B1', PHP_EOL; }}// 商品B2的实现class ProductB2 implements AbstractProductB{ public function show(): void { echo '我是商品B2', PHP_EOL; }}// 抽象工厂接口interface AbstractFactory{ // 创建商品A public function CreateProductA(): AbstractProductA; // 创建商品B public function CreateProductB(): AbstractProductB;}// 工厂1 实现商品A1 和 商品A2class ConcreteFactory1 implements AbstractFactory{ public function CreateProductA(): AbstractProductA { return new ProductA1(); } public function CreateProductB(): AbstractProductB { return new ProductB1(); }}// 工厂2 实现商品A2 和 商品B2class ConcreteFactory2 implements AbstractFactory{ public function CreateProductA(): AbstractProductA { return new ProductA2(); } public function CreateProductB(): AbstractProductB { return new ProductB2(); }}// 测试$factory1 = new ConcreteFactory1();$factory1ProductA = $factory1->CreateProductA();$factory1ProductB = $factory1->CreateProductB();$factory1ProductA->show();$factory1ProductB->show();$factory2 = new ConcreteFactory2();$factory2ProductA = $factory2->CreateProductA();$factory2ProductB = $factory2->CreateProductB();$factory2ProductA->show();$factory2ProductB->show();
运行结果:
5、装饰器模式
描述:使用装饰器给基础类的实例化对象动态的添加属性或方法
就像给返回的对象一层一层的添加装饰品
下面直接 上代码
。
interface Component{ public function operation();}class ConcreteComponent implements Component{ public function operation() { return '我要化妆了'; }}// 装饰器的抽象类abstract class Decorator implements Component{ protected $component; // 这里传入的是原本的基础类实例 public function __construct(Component $component) { $this->component = $component; }}// 装饰器的实现类 添加属性示例class ConcreteDecoratorA extends Decorator{ public $addedState = 1; // 没有实际意义 用于区别ConcreteDecoratorB public function operation() { // 给原始的方法 添加内容 echo $this->component->operation() . '眼线笔' . $this->addedState . '只', PHP_EOL; }}// 添加方法示例class ConcreteDecoratorB extends Decorator{ public function operation() { $this->component->operation(); $this->addedStateB(); } public function addedStateB() { echo '我是第二个装饰器'; }}// 测试$component = new ConcreteComponent();$component->operation();// 第一层装饰$component = new ConcreteDecoratorA($component);$component->operation();// 第二层装饰$component = new ConcreteDecoratorB($component);$component->operation();
运行结果:
6、适配器模式
描述:在旧的代码中预留一块逻辑,新的代码需要适配旧的代码时,再去补全这块内容
下面直接 上代码
。
interface Target{ function Request(): void;}// 适配器class Adapter implements Target{ private $adaptee; function __construct($adaptee) { $this->adaptee = $adaptee; } function Request(): void { $this->adaptee->SpecificRequest(); }}// 具体要实现功能的逻辑class Adaptee{ function SpecificRequest(): void { echo '我是适配器预留的逻辑'; }}// 测试$adaptee = new Adaptee();$adapter = new Adapter($adaptee);$adapter->Request();
运行结果:
7、观察者模式
描述:创建待观察列表,列表中存在观察者对象的值才会执行(将当前对象传入观察者类)
下面直接 上代码
。
interface Observer{ public function update(Subject $subject): void;}class ConcreteObserver implements Observer{ private $observerState = ''; function update(Subject $subject): void { $this->observerState = $subject->getState(); echo '执行观察者操作!当前状态:' . $this->observerState, PHP_EOL; }}class Subject{ private $observers = []; private $stateNow = ''; // 往要观察列表中添加对象 public function attach(Observer $observer): void { array_push($this->observers, $observer); } // 从要观察列表中删除对象 public function detach(Observer $observer): void { $position = 0; foreach ($this->observers as $ob) { if ($ob === $observer) { array_splice($this->observers, ($position), 1); } ++$position; } } public function notify(): void { foreach ($this->observers as $ob) { $ob->update($this); } }}// 具体实现class ConcreteSubject extends Subject{ public function setState($state) { $this->stateNow = $state; $this->notify(); } public function getState() { return $this->stateNow; }}// 测试$observer = new ConcreteObserver();$observer2 = new ConcreteObserver();$subject = new ConcreteSubject();// 添加要观察的对象$subject->attach($observer);$subject->setState('哈哈哈哈哈');// 从列表中删除$subject->detach($observer);// 这里不会再观察值的变化了$subject->setState('嘿嘿嘿嘿嘿');// 测试第二个观察者$subject->attach($observer2);$subject->setState('呵呵呵呵呵');
运行结果:
8、迭代器模式
描述:这种设计模式用的相对较少,学习一下
下面直接 上代码
。
interface MyIterator{ public function First(); public function Next(); public function IsDone(); public function CurrentItem();}class ConcreteIterator implements MyIterator{ private $list; private $index; public function __construct($list) { $this->list = $list; $this->index = 0; } public function First() { $this->index = 0; } public function Next() { $this->index++; } // 下标大于或等于数组的总长度了 返回true public function IsDone() { return $this->index >= count($this->list); } // 返回当前下标的数组信息 public function CurrentItem() { return $this->list[$this->index]; }}// 创建聚合对象的接口interface Aggregate{ public function CreateIterator();}class ConcreteAggregate implements Aggregate{ public function CreateIterator() { $list = ['a', 'b', 'c', 'd']; return new ConcreteIterator($list); }}// 测试$agreegate = new ConcreteAggregate();$iterator = $agreegate->CreateIterator();while (!$iterator->IsDone()) { echo $iterator->CurrentItem(), PHP_EOL; $iterator->Next();}$iterator->First();echo $iterator->CurrentItem(), PHP_EOL;$iterator->Next();echo $iterator->CurrentItem(), PHP_EOL;
运行结果:
9、原型模式
描述:主要行为是对 对象进行克隆,可以减少创建对象时的开销
使用clone操作复制对象时,当被复制的对象有对其它对象的引用的时候,引用的对象将不会被复制。
下面直接 上代码
。
abstract class Prototype{ public $a; public $b; public function __construct() { echo 'create' . PHP_EOL; } abstract public function __clone();}class ConcretePrototype1 extends Prototype{ // 克隆对象时 执行这个魔术方法 public function __clone() { }}class ConcretePrototype2 extends Prototype{ // 将内层对象也 拷贝一份 public function __clone() { $this->b = clone $this->b; }}class Client{ public function operation() { // 浅拷贝 外层对象地址不一样 内层对象地址一样 $p1 = new ConcretePrototype1(); $p1->a = 123; $p1->b = new ConcretePrototype2(); // 因为这里是克隆的 所以没有执行构造方法 $p2 = clone $p1; var_dump($p1, $p2); // 深拷贝 外层对象地址不一样 内层对象地址也不一样 $s1 = new ConcretePrototype2(); $s1->a = 456; $s1->b = new ConcretePrototype1(); $s2 = clone $s1; var_dump($s1, $s2); // 扩展:序列化方式 实现深拷贝 $a1 = new ConcretePrototype1(); $a1->a = 789; $a1->b = new ConcretePrototype2(); $tmp = unserialize(serialize($a1)); var_dump($a1, $tmp); }}// 测试$c = new Client();$c->operation();
运行结果:
10、命令模式
描述:实现调用者与执行者的解耦
下面直接 上代码
。
// 请求者 举例:服务员class Invoker{ public $command; public function setCommand($command) { $this->command = $command; } public function exec() { $this->command->execute(); }}// 命令 举例:菜单abstract class Command{ protected $receiver; public function __construct(Receiver $receiver) { $this->receiver = $receiver; } abstract public function execute();}class ConcreteCommand extends Command{ // 举例:点菜功能 public function execute() { $this->receiver->action(); }}// 执行者 举例:厨师角色class Receiver{ public $name; public function __construct($name) { $this->name = $name; } public function action() { echo $this->name . '命令执行了!', PHP_EOL; }}// 测试// 准备执行者$receiverA = new Receiver('A');$receiverB = new Receiver('B');// 准备命令$commandOne = new ConcreteCommand($receiverA);$commandTwo = new ConcreteCommand($receiverB);// 请求者$invoker = new Invoker();$invoker->setCommand($commandOne);$invoker->exec();$invoker->setCommand($commandTwo);$invoker->exec();
运行结果:
11、策略模式
描述:传递不同的参数来调用不同的方法,与上面的简单工厂很像
下面直接 上代码
。
interface Strategy{ function way();}class Walk implements Strategy{ public function way(){ echo '策略A', PHP_EOL; }}class Bus implements Strategy{ public function way(){ echo '策略B', PHP_EOL; }}class Stu{ public static function play($obj){ $obj->way(); }}// 测试Stu::play(new Walk);Stu::play(new Bus);
运行结果:
12、责任链模式
描述:上一级持有下一级的引用,执行结果没有满足条件再通过下一级引用继续判断。可用于对请求参数进行层层过滤
下面直接 上代码
。
abstract class Handler{ protected $successor; // 设置检查下一级的对象 public function setSuccessor($successor) { $this->successor = $successor; } abstract public function HandleRequest($request);}class ConcreteHandler1 extends Handler{ public function HandleRequest($request) { if (is_numeric($request)) { return '请求参数是数字:' . $request; } else { // 参数非数字 传入下一层的HandleRequest return $this->successor->HandleRequest($request); } }}class ConcreteHandler2 extends Handler{ public function HandleRequest($request) { if (is_string($request)) { return '请求参数是字符串' . $request; } else { return $this->successor->HandleRequest($request); } }}class ConcreteHandler3 extends Handler{ public function HandleRequest($request) { return '我也不知道请求参数是啥了,自动识别中……' . gettype($request); }}// 测试$handle1 = new ConcreteHandler1();$handle2 = new ConcreteHandler2();$handle3 = new ConcreteHandler3();// 设置下一级 持有下一级的引用$handle1->setSuccessor($handle2);$handle2->setSuccessor($handle3);// 测试结果$requests = [22, 'aa', 55, 'cc', [1, 2, 3], null, new stdClass];foreach ($requests as $request) { echo $handle1->HandleRequest($request) . PHP_EOL;}
运行结果:
13、代理模式
描述:通过代理类执行真实类中的代码
下面直接 上代码
。
interface Agent{ public function Request();}// 真实类class RealSubject implements Agent{ function Request() { echo '真实的操作', PHP_EOL; }}// 代理类class Proxy implements Agent{ private $realSubject; public function __construct() { $this->realSubject = new RealSubject(); } public function Request() { echo '代理的操作', PHP_EOL; $this->realSubject->Request(); }}// 测试$proxy = new Proxy();$proxy->Request();
运行结果:
14、享元模式
描述:将对象缓存起来 只创建一次,第二次请求不会再创建对象了,节省实例化开销
下面直接 上代码
。
interface Flyweight{ public function operation($extrinsicState): void;}class ConcreteFlyweight implements Flyweight{ // 内部状态 private $intrinsicState = 101; function operation($extrinsicState): void { echo '共享享元对象' . ($extrinsicState + $this->intrinsicState) . PHP_EOL; }}class UnsharedConcreteFlyweight implements Flyweight{ private $allState = 1000; public function operation($extrinsicState): void { echo '非共享享元对象:' . ($extrinsicState + $this->allState) . PHP_EOL; }}// 享元工厂class FlyweightFactory{ private $flyweights = []; public function getFlyweight($key): Flyweight { // key不存在 则添加一个享元对象 if (!array_key_exists($key, $this->flyweights)) { echo '创建了享元对象', PHP_EOL; $this->flyweights[$key] = new ConcreteFlyweight(); } return $this->flyweights[$key]; }}// 测试$factory = new FlyweightFactory();$extrinsicState = 100;$flyA = $factory->getFlyweight('a');$flyA->operation(--$extrinsicState);$flyB = $factory->getFlyweight('b');$flyB->operation(--$extrinsicState);$flyD = new UnsharedConcreteFlyweight();$flyD->operation(--$extrinsicState);// 因为上面创建过享元对象了 这里不会再次创建$flyA = $factory->getFlyweight('a');$flyA->operation(--$extrinsicState);
运行结果:
15、组合模式
描述:构建树形结构,给根节点添加叶子节点与组合节点
下面直接 上代码
。
abstract class Combination{ protected $name; public function __construct($name) { $this->name = $name; } abstract public function Operation(int $depth); abstract public function Add(Combination $combination); abstract public function Remove(Combination $combination);}// 组合节点class Composite extends Combination{ private $combinationList; public function Operation(int $depth) { // 重复一个字符串 $depth是重复次数 echo str_repeat('-', $depth) . $this->name . PHP_EOL; foreach ($this->combinationList as $combination) { $combination->Operation($depth + 2); } } public function Add(Combination $combination) { $this->combinationList[] = $combination; } public function Remove(Combination $combination) { $position = 0; foreach ($this->combinationList as $child) { if ($child == $combination) { array_splice($this->combinationList, ($position), 1); } $position++; } } // 打印当前节点内容 public function GetChild(int $i) { return $this->combinationList[$i]; } public function getAll() { var_dump($this->combinationList); }}// 叶子节点class Leaf extends Combination{ public function Add(Combination $combination) { echo '叶子结点不需要add' . PHP_EOL; } public function Remove(Combination $combination) { echo '叶子节点不需要remove' . PHP_EOL; } public function Operation(int $depth) { // 叶子节点直接打印深度 echo str_repeat('-', $depth) . $this->name . PHP_EOL; }}// 测试$root = new Composite('root');$root->Add(new Leaf('Leaf A'));$root->Add(new Leaf('Leaf B'));$comp = new Composite('Composite X');$comp->Add(new Leaf('Leaf XA'));$comp->Add(new Leaf('Leaf XB'));$root->Add($comp);$comp2 = new Composite('Composite XY');$comp2->Add(new Leaf('Leaf XYA'));$comp2->Add(new Leaf('Leaf XYB'));$comp->Add($comp2);$root->Add(new Leaf('Leaf C'));$leaf = new Leaf('Leaf D');$root->Add($leaf);$root->Remove($leaf);$root->Operation(1);
运行结果:
16、中介者模式
描述:在终端发出信息,通过中介者类调节发送
下面直接 上代码
。
// 中介者类abstract class Mediator{ abstract public function Send(string $message, Colleague $colleague);}class ConcreteMediator extends Mediator{ // 同事1 public $colleague1; // 同事2 public $colleague2; public function Send(string $message, Colleague $colleague) { if ($colleague === $this->colleague1) { // 外部传入等于同事1 则同事2接收到一条信息 $this->colleague2->Notify($message); } else { $this->colleague1->Notify($message); } }}// 同事类abstract class Colleague{ protected $mediator; public function __construct(Mediator $mediator) { $this->mediator = $mediator; }}// 同事1class ConcreteColleague1 extends Colleague{ public function Send(string $message) { $this->mediator->Send($message, $this); } public function Notify(string $message) { echo '同事1接收到信息' . $message, PHP_EOL; }}// 同事2class ConcreteColleague2 extends Colleague{ public function Send(string $message) { $this->mediator->Send($message, $this); } public function Notify(string $message) { echo '同事2接收到信息' . $message, PHP_EOL; }}// 测试$m = new ConcreteMediator();$c1 = new ConcreteColleague1($m);$c2 = new ConcreteColleague2($m);$m->colleague1 = $c1;$m->colleague2 = $c2;$c1->Send('你吃饭了吗?');$c2->Send('没呢 走?');
运行结果:
17、建造者模式
描述:往基类中配置属性,一步一步去构建完善。因为不是所有配置都是必须的,所以可以根据需求随时添加
下面直接 上代码
。
class House{ private $parts = []; public function Add(string $part): void { $this->parts[] = $part; } public function Show(): void { echo PHP_EOL . '产品创建 ----', PHP_EOL; foreach ($this->parts as $part) { echo $part, PHP_EOL; } }}// 建造者interface Builder{ public function BuildPartA(): void; public function BuildPartB(): void; public function GetResult(): House;}class ConcreteBuilder1 implements Builder{ private $product; public function __construct() { $this->product = new House(); } public function BuildPartA(): void { $this->product->Add('部件A'); } public function BuildPartB(): void { $this->product->Add('部件B'); } public function GetResult(): House { return $this->product; }}class ConcreteBuilder2 implements Builder{ private $product; public function __construct() { $this->product = new House(); } public function BuildPartA(): void { $this->product->Add('部件X'); } public function BuildPartB(): void { $this->product->Add('部件Y'); } public function GetResult(): House { return $this->product; }}class Director{ public function Construct(Builder $builder) { $builder->BuildPartA(); $builder->BuildPartB(); }}// 测试$director = new Director();$b1 = new ConcreteBuilder1();$b2 = new ConcreteBuilder2();$director->Construct($b1);$p1 = $b1->GetResult();$p1->Show();$director->Construct($b2);$p2 = $b2->GetResult();$p2->Show();
运行结果:
18、备忘录模式
描述:类似存档功能,下面实现了一个保存状态案例
下面直接 上代码
。
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; }}// 备忘录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();
运行结果:
19、桥接模式
描述:分离开具体的实现类和抽象类。如果单纯继承会有耦合问题,该模式将具体的实现分离出去
下面直接 上代码
。
// 实现类interface Implementor{ public function OperationImp();}class ConcreteImplementorA implements Implementor{ public function OperationImp() { echo '具体实现A', PHP_EOL; }}class ConcreteImplementorB implements Implementor{ public function OperationImp() { echo '具体实现B', PHP_EOL; }}// 抽象类abstract class Abstraction{ protected $imp; public function SetImplementor(Implementor $imp) { $this->imp = $imp; } abstract public function Operation();}class BefinedAbstraction extends Abstraction{ public function Operation() { $this->imp->OperationImp(); }}// 测试$impA = new ConcreteImplementorA();$impB = new ConcreteImplementorB();$ra = new BefinedAbstraction();$ra->SetImplementor($impA);$ra->Operation();$ra->SetImplementor($impB);$ra->Operation();
运行结果:
20、门面模式
描述:对多个系统进行封装 方便外部调用,也就是MVC的思想
下面直接 上代码
。
class Facade{ // 定义四个子系统 private $subStytemOne; private $subStytemTwo; private $subStytemThree; private $subStytemFour; public function __construct() { $this->subStytemOne = new SubStytemOne(); $this->subStytemTwo = new SubStytemTwo(); $this->subStytemThree = new SubStytemThree(); $this->subStytemFour = new SubStytemFour(); } // 调用前两个子系统的功能 public function MethodA() { $this->subStytemOne->MethodOne(); $this->subStytemTwo->MethodTwo(); } public function MethodB() { $this->subStytemOne->MethodOne(); $this->subStytemTwo->MethodTwo(); $this->subStytemThree->MethodThree(); $this->subStytemFour->MethodFour(); }}class SubStytemOne{ public function MethodOne() { echo '子系统方法一', PHP_EOL; }}class SubStytemTwo{ public function MethodTwo() { echo '子系统方法二', PHP_EOL; }}class SubStytemThree{ public function MethodThree() { echo '子系统方法三', PHP_EOL; }}class SubStytemFour{ public function MethodFour() { echo '子系统方法四', PHP_EOL; }}// 测试$facade = new Facade();$facade->MethodA();$facade->MethodB();
运行结果:
21、模板方法模式
下面直接 上代码
。
abstract class AbstractClass{ public function TemplateMethod() { $this->PrimitiveOperation1(); $this->PrimitiveOperation2(); } abstract public function PrimitiveOperation1(); abstract public function PrimitiveOperation2();}class ConcreteClassA extends AbstractClass{ public function PrimitiveOperation1() { echo '具体类A 实现方法1', PHP_EOL; } public function PrimitiveOperation2() { echo '具体类A 实现方法2', PHP_EOL; }}class ConcreteClassB extends AbstractClass{ public function PrimitiveOperation1() { echo '具体类B 实现方法1', PHP_EOL; } public function PrimitiveOperation2() { echo '具体类B 实现方法2', PHP_EOL; }}// 测试$c = new ConcreteClassA();$c->TemplateMethod();$c = new ConcreteClassB();$c->TemplateMethod();
运行结果:
22、状态模式
描述:通过上下文切换类的状态 就像换了一个类操作。可以解决if else嵌套问题
下面直接 上代码
。
// 上下文类class Context{ private $state; public function SetState(State $state): void { $this->state = $state; } public function Request(): void { $this->state = $this->state->Handle(); }}// 实现类interface State{ public function Handle(): State;}class ConcreteStateA implements State{ public function Handle(): State { echo '当前是A状态', PHP_EOL; return new ConcreteStateB(); }}class ConcreteStateB implements State{ public function Handle(): State { echo '当前是B状态', PHP_EOL; return new ConcreteStateA(); }}// 测试$c = new Context();$stateA = new ConcreteStateA();$c->SetState($stateA);$c->Request();$c->Request();$c->Request();
运行结果:
23、访问者模式
描述:适用于数据结构稳定的结构,例如账单只有收入支出
下面直接 上代码
。
interface Visitor{ function VisitConcreteElementA(ConcreteElementA $a); function VisitConcreteElementB(ConcreteElementB $b);}// 一号访问者class ConcreteVisitor1 implements Visitor{ public function VisitConcreteElementA(ConcreteElementA $a) { echo get_class($a) . '被' . get_class($this) . '访问', PHP_EOL; } public function VisitConcreteElementB(ConcreteElementB $b) { echo get_class($b) . '被' . get_class($this) . '访问', PHP_EOL; }}// 二号访问者class ConcreteVisitor2 implements Visitor{ public function VisitConcreteElementA(ConcreteElementA $a) { echo get_class($a) . '被' . get_class($this) . '访问', PHP_EOL; } public function VisitConcreteElementB(ConcreteElementB $b) { echo get_class($b) . '被' . get_class($this) . '访问', PHP_EOL; }}// 实体类interface Element{ public function Accept(Visitor $v);}class ConcreteElementA implements Element{ public function Accept(Visitor $v) { $v->VisitConcreteElementA($this); } public function OperationA() { }}class ConcreteElementB implements Element{ public function Accept(Visitor $v) { $v->VisitConcreteElementB($this); } public function OperationB() { }}class ObjectStructure{ private $elements = []; public function Attach(Element $element) { $this->elements[] = $element; } public function Detach(Element $element) { $position = 0; foreach ($this->elements as $e) { if ($e == $element) { unset($this->elements[$position]); break; } $position++; } } public function Accept(Visitor $visitor) { foreach ($this->elements as $e) { $e->Accept($visitor); } }}// 测试$o = new ObjectStructure();// 传入两个实体类$o->Attach(new ConcreteElementA());$o->Attach(new ConcreteElementB());// 创建访问者$v1 = new ConcreteVisitor1();$v2 = new ConcreteVisitor2();$o->Accept($v1);$o->Detach(new ConcreteElementA());$o->Accept($v2);
运行结果:
24、注册树模式
描述:注册树模式通过将对象实例注册到一颗全局的对象树上,就类似将对象统一数组中管理,需要的时候从对象树上采摘的模式设计方法。
无论是通过单例模式、工厂模式还是二者结合生成的对象,都统统插到注册树上。需要使用某个对象的时候直接从注册树上取一下就好,这和我们使用全局变量一样方便实用,而且注册树模式还为其他模式提供了一种非常好的想法。
下面直接 上代码
。
class Single{ // 创建单例 public $hash; static protected $ins = null; final protected function __construct(){ // 声明为final 防止被子类重写覆盖 $this->hash = rand(1, 9999); } static public function getInstance(){ if(self::$ins instanceof self){ return self::$ins; } self::$ins = new self(); return self::$ins; }}class RandFactory{ // 工厂模式 public static function factory(){ return Single::getInstance(); }}class Register{ // 注册树 protected static $objects; // 静态属性 保留值 public static function set($alias, $object){ self::$objects[$alias] = $object; } public static function get($alias){ return self::$objects[$alias]; } public static function _unset($alias){ unset(self::$objects[$alias]); }}Register::set('rand', RandFactory::factory());$object = Register::get('rand');var_dump($object);
运行结果:
来源地址:https://blog.csdn.net/qq_45652915/article/details/127555480
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341