理解23种设计模式(php)

tips:本文只介绍接口的设计模式,所以牵涉到模板的模板方法模式和builder设计模式不做介绍,感兴趣的参考该文:
https://www.cnblogs.com/zyrblog/tag/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/default.html?page=1

面向对象设计的原则:高内聚,低耦合,对扩展开放,对修改关闭的开闭原则;设计模式应该遵从该原则;设计模式更多的是面向对象编程的一种设计理念,很多时候并没有固定的格式,并且有一些设计模式之间的界限很模糊,需要掌握理念,融汇贯通,不要执着于定式

tips:以下都是示例代码,实际业务需求要复杂得多,仅作为入门学习

1、迭代器

特点: 对类的属性进行遍历,优点(隐藏遍历逻辑)

// 接口
<?php

namespace App\Service;

interface CommonServiceInterface
{
    public function hasNext();
    public function next();
    public function add($user);
    public function delete($pointer);
}

// 实现类
<?php

namespace App\Service;

class CommonService implements CommonServiceInterface
{
    private $set = [];
    private $pointer = 0;
    public function hasNext()
    {
        if (isset($this->set[$this->pointer])) {

            return true;
        } else {

            return false;
        }
    }

    public function next()
    {
        return $this->set[$this->pointer++];
    }

    public function add($user)
    {
        // 存在则不能添加
        if (in_array($user,$this->set)) {

            throw new \Exception('已存在');
        }
        array_push($this->set,$user);
    }

    public function delete($user)
    {
        $key = array_search($user,$this->set);

        if ($key) {

            unset($this->set[$key]);
            // 处理指针
            if ($this->pointer < $key) {
                $this->pointer --;
            }

            return true;
        } else {
            return false;
        }

    }
}

 // 测试
$commonService = new CommonService();
  $commonService->add(4);
  $commonService->add(2);
  $commonService->add(3);

  while($commonService->hasNext()) {
      echo $commonService->next();
  }

// 结果
在这里插入图片描述

2、适配器

特点:根据不同的类型,选择执行对应的类型的成员方法 (适配不同的类型)

// 接口
<?php

namespace App\Service;

interface CommonServiceInterface
{
    public function v220();
    public function v110();
}

// 实现
<?php

namespace App\Service;

class CommonService implements CommonServiceInterface
{

    public function v220()
    {
       echo 'this is 220 voltage';
    }

    public function v110()
    {
        echo 'this is 110 voltage';
    }
}

// 测试适配器 假设电压是220伏
$v = 220;

 $commonService = new CommonService();

 $commonService->{'v'.$v}();

// 结果
在这里插入图片描述

3、普通工厂

特点:不包含抽象类

// 接口
<?php

namespace App\Service;

interface CommonServiceInterface
{
    public function make();
    public function test();
}

// 实现
<?php

namespace App\Service;

class CommonService implements CommonServiceInterface
{
    public function make()
    {
        echo '制造一台设备'.PHP_EOL;
    }

    public function test()
    {
        echo '设备测试正常'.PHP_EOL;
    }

    public function out()
    {
        echo '设备发往山东'.PHP_EOL;
    }
}

// 测试普通工厂
        $commonService = new CommonService();
        $commonService->make();
        $commonService->test();
        $commonService->out();

// 结果:
在这里插入图片描述

4、抽象工厂

特点:工厂是抽象类,包含抽象方法,功能相比普通工厂要复杂,需要实现抽象方法

// 接口
<?php

namespace App\Service;

interface CommonServiceInterface
{
    public function make();
    public function test();
    public function out();
}

// 抽象工厂类,实现工厂接口
<?php

namespace App\Service;

abstract class CommonServiceAbstract implements CommonServiceInterface
{
    protected $makeout;

    abstract public function toMake();

    public function make()
    {
        $this->toMake();
        echo $this->makeout;
    }


    public function test()
    {
        echo '设备测试正常'.PHP_EOL;
    }

    public function out()
    {
        echo '设备发往山东'.PHP_EOL;
    }
}

// 实现抽象工厂内的抽象方法
<?php

namespace App\Service;

class CommonService extends CommonServiceAbstract
{
    public function toMake()
    {
        $this->makeout = "制造出一台汽车\n";
    }
}

// 测试抽象工厂
        $commonService = new CommonService();
        $commonService->make();
        $commonService->test();
        $commonService->out();

结果
在这里插入图片描述

5、单例设计模式

特点:定义很简单,就是类只实例化一次的设计模式,节省服务器资源

// 单例类,通过静态属性$instance持久化保存类的实例
<?php

namespace App\Service;

class CommonService
{
    private static $instance;

    public static function instance()
    {
          if (!self::$instance) {

              self::$instance = new self();
          }

         return self::$instance;
    }

    public function hello()
    {
        echo "你好啊\n";
    }
}

// 测试单例
        $instance = CommonService::instance();
        $instance->hello();

        $instance = CommonService::instance();
        $instance->hello();

// 结果 只有第一次进行了实例化,第二次不再进行实例化了

在这里插入图片描述

6、克隆模式

特点:克隆一个对象,克隆以后,原本对象和副本对象是完全独立互不干扰的,简单实用

// 接口
<?php

namespace App\Service;

interface CommonServiceInterface
{
    public function say();
}

// 实现
<?php

namespace App\Service;

class CommonService implements CommonServiceInterface
{
    public function say()
    {
        echo '说话方法';
    }
}

// 测试
 // 测试单例
        $clones = [new CommonService()];
        $clones[0]->say();

//结果
在这里插入图片描述

7、桥接模式

特点:在原有抽象类的基础上,增加新的方法(抽象方法),实现新的功能,如果包含抽象方法,则类似抽象工厂,能实现比抽象工厂更加复杂的功能;

// 接口

<?php

namespace App\Service;

interface CommonServiceInterface
{
    public function make();
    public function test();
    public function out();
}

// 桥接 增加了更为复杂的抽象方法,实现精细化的功能
<?php

namespace App\Service;

abstract class CommonServiceAbstract implements CommonServiceInterface
{
    protected $makeout;
    protected $body;
    protected $wheel;
    protected $chassis;

    public function toMake()
    {
        $this->makeout = $this->body.'--'.$this->wheel.'--'.$this->chassis;
    }

    abstract public function toMakeBody();

    abstract public function toMakeWheel();

    abstract public function toMakeChassis();

    public function make()
    {
        $this->toMake();

        echo $this->makeout."<br />";
    }


    public function test()
    {
        echo "设备测试正常<br />";
    }

    public function out()
    {
        echo '设备发往山东<br />';
    }
}

// 实现
<?php

namespace App\Service;

class CommonService extends CommonServiceAbstract
{
    public function toMakeBody()
    {
        $this->body = '碳纤维车身';
    }

    public function toMakeWheel()
    {
        $this->wheel = '米其林轮胎';
    }

    public function toMakeChassis()
    {
        $this->chassis = '高韧性底盘';
    }
}

// 测试
  $commonService = new CommonService();
        $commonService->toMakeBody();
        $commonService->toMakeWheel();
        $commonService->toMakeChassis();
        $commonService->make();
        $commonService->test();
        $commonService->out();

// 结果
在这里插入图片描述

8、策略模式

特点:功能与适配器模式类似,针对不同的策略类型,执行不同的方法,区别是:策略模式更复杂一些,将执行过程提炼成单独的工厂类,使得操作类和具体执行类解耦,本质上是外观设计模式+普通工厂的组合

// 接口
<?php

namespace App\Service;

interface CommonServiceInterface
{
    public function make();
    public function test();
    public function out();
}

// 策略类(操作类,外观模式)
<?php

namespace App\Service;

class CommonService implements CommonServiceInterface
{
    private $tool;
    public function __construct($toolInstance)
    {
        $this->tool = new $toolInstance();
    }

    public function make()
    {
        echo $this->tool->toMake();
    }

    public function test()
    {
        $this->wheel = '米其林轮胎';
    }

    public function out()
    {
        $this->chassis = '高韧性底盘';
    }
}

// 策略类(两个执行类,普通工厂)
造车
<?php

namespace App\Service;

class CarService
{

    public function toMake()
    {
        echo '我造出了一辆汽车<br>';
    }
}

造船
<?php

namespace App\Service;


class BoatService
{

    public function toMake()
    {
        echo '我造出了一艘船<br>';
    }
}

// 测试
$commonService = new CommonService(CarService::class);
        $commonService->make();
        $commonService->test();
        $commonService->out();

        $commonService = new CommonService(BoatService::class);
        $commonService->make();
        $commonService->test();
        $commonService->out();

// 结果
在这里插入图片描述

9、组合模式

特点:将多个具有相同父类的子类组装在一起,并且所有子类具有相同的结构

// 接口
<?php

namespace App\Service;

interface CommonServiceInterface
{
    public function add($item);
    public function out();
}

// 子类1
<?php

namespace App\Service;

class CarService implements CommonServiceInterface
{
    private $out;
    public function add($item)
    {
        $this->out = $item;
    }

    public function out()
    {
        echo $this->out;
    }
}

// 子类2
<?php

namespace App\Service;

class CarService implements CommonServiceInterface
{
    private $out;
    public function add($item)
    {
        $this->out = $item;
    }

    public function out()
    {
        echo $this->out;
    }
}

// 子类2(组合类)
<?php

namespace App\Service;

class CommonService implements CommonServiceInterface
{
    private $out;
    public function add($item)
    {
        $this->out[] = $item;
    }

    public function out()
    {
    	for($i=0;$i<count($this->out);$i++){
    		echo $this->out[$i]->out();
		}
        
    }
}

// 测试
$commonService = new CommonService();
        $car = new CarService();
        $car->add('我造出了一辆车');
        $boat = new BoatService();
        $boat->add('我造出了一艘船');
        $commonService->add($car);
        $commonService->add($boat);

        $commonService->out();

// 结果
在这里插入图片描述

10、装饰器模式

特点:给输出的东西增加一些点缀,采用递归,很实用,但是逻辑有点复杂

// 接口
<?php

namespace App\Service;

interface CommonServiceInterface
{
    public function getColumns();
    public function getRows();
    public function getText($rowId);
    public function show();
}

// 装饰类1(增加侧边修饰)
<?php

namespace App\Service;

class SideService implements CommonServiceInterface
{
    private $content;
    private $char;
    private $isInit;

    public function __construct($content,$char,$isInit)
    {
        $this->content = $content;
        $this->char = $char;
        $this->isInit = $isInit;
    }

    public function getColumns()
    {
        if ($this->isInit){

            return strlen($this->content) + 2;

        } else {

            return $this->content->getColumns() + 2;
        }

    }

    public function getRows()
    {
        if ($this->isInit) {

            return 1;
        } else {
            return $this->content->getRows();
        }
    }

    public function getText($rowId)
    {
        if ($this->isInit) {

            return $this->char.$this->content.$this->char;
        } else {
            return $this->char.$this->content->getText($rowId).$this->char;
        }

    }

    public function show()
    {
        if ($this->isInit) {

            echo $this->char.$this->content.$this->char.'<br>';
        } else {
            for($i=0;$i<$this->getRows();$i++){

                echo $this->char.$this->content->getText($i).$this->char.'<br>';
            }
        }

    }
}

// 装饰类2(增加包边修饰)
<?php

namespace App\Service;


class SurroundingService implements CommonServiceInterface
{
    private $content;
    private $isInit;

    public function __construct($content,$isInit)
    {
        $this->content = $content;
        $this->isInit = $isInit;
    }

    public function getColumns()
    {
        if ($this->isInit){

            return strlen($this->content) + 2;

        } else {

            return $this->content->getColumns() + 2;
        }
    }

    public function getRows()
    {
        if ($this->isInit){

            return 3;

        } else {

            return $this->content->getRows() + 2;
        }
    }

    public function getText($rowId)
    {
        if ($this->isInit) {

            if ($rowId == 0) {
                return '+'.$this->makeLine('-',$this->getColumns()-2).'+';
            } else if ($rowId == 2) {
                return '+'.$this->makeLine('-',$this->getColumns()-2).'+';
            } else {
                return '||'.$this->content.'||';
            }

        } else {

            if ($rowId == 0) {
                return '+'.$this->makeLine('-',$this->getColumns()-2).'+';
            } else if ($rowId == $this->getRows() - 1) {
                return '+'.$this->makeLine('-',$this->getColumns()-2).'+';
            } else {
                return '||'.$this->content->getText($rowId-1).'||';
            }
        }

    }

    public function show()
    {
        if ($this->isInit) {
            for($i=0;$i<$this->getRows();$i++){

                if ($i == 0) {
                    echo '+'.$this->makeLine('-',$this->getColumns()-2).'+<br>';
                } else if ($i == 2) {
                    echo '+'.$this->makeLine('-',$this->getColumns()-2).'+<br>';
                } else {
                    echo '||'.$this->content.'||<br>';
                }

            }

        } else {
            for($i=0;$i<$this->getRows();$i++){

                if ($i == 0) {

                    echo '+'.$this->makeLine('-',$this->getColumns()-2).'+<br>';
                } else if ($i == $this->getRows() - 1) {

                    echo '+'.$this->makeLine('-',$this->getColumns()-2).'+<br>';
                } else {
                    echo '||'.$this->content->getText($i-1).'||<br>';
                }
            }
        }
    }

    private function makeLine($char,$len)
    {
        $str = '';
        for($i=0;$i<$len;$i++){
            $str .= $char;
        }
        return $str;
    }
}

// 测试
 $s0 = new SurroundingService('张同学',true);
        $s1 = new SideService($s0,'*',false);
        $s2 = new SurroundingService($s1,false);
        $s3 = new SurroundingService($s2,false);
        $s4 = new SideService($s3,'*',false);
        $s5 = new SurroundingService($s4,false);
        echo $s5->show();

// 结果
在这里插入图片描述

11、访问者模式

特点:访问属性的方法单独提取成为一个类,方便访问方法的修改;

// 接口
<?php

namespace App\Service;

interface CommonServiceInterface
{
    public function add($item);
    public function visit($visit);
}

// 实现
<?php

namespace App\Service;

class SideService implements CommonServiceInterface
{
    private $content;

    public function add($item)
    {
        $this->content[] = $item;
    }

    public function visit($visit)
    {
        return $visit->out($this->content);
    }
}

// 访问类
<?php

namespace App\Service;

class CommonService
{
    public function out($item)
    {
        return $item;
    }
}

// 测试
$side = new SideService();
        $side->add('张三');
        $side->add('李四');
        $side->add('王五');
        $visit = new CommonService();
        dd($side->visit($visit));

// 结果
在这里插入图片描述

12、责任链模式

特点:问题如果在这层没办法处理,就传递到下一层,直到最终被解决或无法解决,利用递归实现添加责任链;

// 接口
<?php

namespace App\Service;

interface CommonServiceInterface
{
    public function addNextResolve($next);
    public function resolve($problem);
    public function success();
    public function fail();
}

// 责任链1(通用解决类)
<?php

namespace App\Service;

class CommonService implements CommonServiceInterface
{
    private $next;
    private $problem;

    public function addNextResolve($next)
    {
        $this->next = $next;
        return $next;
    }

    public function resolve($problem)
    {
        $this->problem = $problem;
        if (is_numeric($problem)) {
            $this->success();
        } else {
            $this->fail();
        }
    }

    public function success()
    {
        echo '通过通用方法解决了问题';
    }

    public function fail()
    {
        echo '通用方法无法解决问题';
        if ($this->next) {
            $this->next->resolve($this->problem);
        }
    }
}

// 责任链2
<?php

namespace App\Service;

class SideService implements CommonServiceInterface
{
    private $next;
    private $problem;
    public function addNextResolve($next)
    {
        $this->next = $next;
        return $next;
    }

    public function resolve($problem)
    {
        $this->problem = $problem;
        if (is_string($problem)) {
            $this->success();
        } else {
            $this->fail();
        }
    }

    public function success()
    {
        echo '通过 side 方法解决了问题';
    }

    public function fail()
    {
        echo 'side 方法无法解决问题';
        if ($this->next) {
            $this->next->resolve($this->problem);
        }

    }
}

// 责任链3
<?php

namespace App\Service;

class SurroundingService implements CommonServiceInterface
{
    private $next;
    private $problem;
    public function addNextResolve($next)
    {
        $this->next = $next;
        return $next;
    }

    public function resolve($problem)
    {
        $this->problem = $problem;
        if (is_array($problem)) {
            $this->success();
        } else {
            $this->fail();
        }
    }

    public function success()
    {
        echo '通过 surrounding 方法解决了问题';
    }

    public function fail()
    {
        echo 'surrounding 方法 无法解决问题';
    }
}

// 测试
 $common = new CommonService();
        $sideService = new SideService();
        $SurroundingService = new SurroundingService();
        $common->addNextResolve($sideService)->addNextResolve($SurroundingService);
        $common->resolve(true);

// 结果
在这里插入图片描述

13、外观模式 facade

特点:也叫门面设计模式,概念很好理解,通过对复杂的处理方法进行封装,对外暴露易于理解和操作的方法,使用很广,实现简单;

// 门面类
<?php

namespace App\Service;

class CommonService
{
    private $sb;
    private $sth;

    public function __construct($sb,$sth)
    {
        $this->sb = $sb;
        $this->sth = $sth;

    }

    public function eat()
    {
        echo $this->sb.' 在吃 '.$this->sth.'<br>';
    }

    public function sleep()
    {
        echo $this->sb.' 睡在 '.$this->sth.'上<br>';
    }

}

// 测试
 $common = new CommonService('张三','面包');
        $common->sleep();
        $common->eat();

// 结果
在这里插入图片描述

14、 仲裁者模式

特点:通过仲裁者改变类的属性,类似与广播

// 仲裁者类 通过$this注入被仲裁者内,每个被注入的仲裁者该更状态,都会在仲裁者中分发给所有的被仲裁者;
<?php

namespace App\Service;

class CommonService
{
    public $sideService;
    public $surroundingService;

    public function __construct()
    {
        $this->sideService = new SideService(true);
        $this->surroundingService = new SurroundingService(true);

        $this->sideService->addMediator($this);
        $this->surroundingService->addMediator($this);
    }

    public function changeService()
    {
        $this->sideService->shift();
        $this->surroundingService->shift();
    }

    public function show()
    {
        echo $this->sideService->say().'<br>';
        echo $this->surroundingService->say().'<br>';
    }

}

// 被仲裁者1
<?php

namespace App\Service;

class SideService
{
    private $status;
    private $mediator;

    public function __construct($status)
    {
        $this->status = $status;
    }

    public function say()
    {
        if ($this->status) {
            echo '开启状态';
        } else {
            echo '关闭状态';
        }
    }

    public function changeStatus()
    {
        $this->mediator->changeService();
    }

    public function addMediator($mediator)
    {
        $this->mediator = $mediator;
    }

    public function shift()
    {
        $this->status = !$this->status;
    }
}
// 被仲裁者2
<?php

namespace App\Service;

class SurroundingService
{
    private $status;
    private $mediator;

    public function __construct($status)
    {
        $this->status = $status;
    }

    public function say()
    {
        if ($this->status) {
            echo '开启状态';
        } else {
            echo '关闭状态';
        }
    }

    public function addMediator($mediator)
    {
        $this->mediator = $mediator;
    }

    public function changeStatus()
    {
        $this->mediator->changeService();
    }

    public function shift()
    {
        $this->status = !$this->status;
    }

}

// 测试
$common = new CommonService();
        $common->show();
        $common->sideService->changeStatus();;
        $common->show();
        $common->surroundingService->changeStatus();;
        $common->show();

//结果
在这里插入图片描述

15、观察者

特点:根据传入的不同的观察者,执行不同的方法,还是比较容易理解的

// 观察者1
<?php

namespace App\Service;

class SideService
{
    public function say($word)
    {
        echo 'side观察器说'.$word;
    }

}

// 观察者2
<?php

namespace App\Service;

class SurroundingService
{

    public function say($word)
    {
        echo 'surrounding观察器说'.$word;
    }

}

// 普通类
<?php

namespace App\Service;

class CommonService
{
    public $observer;
    public $word;

    public function __construct($word,$observer)
    {
        $this->word = $word;
        $this->observer = $observer;
    }

    public function show()
    {
        $this->observer->say($this->word);
    }

}

// 测试
$common = new CommonService('haha',new SideService());
        $common->show();

//结果
在这里插入图片描述

16、备忘录模式

特点:比较简单,把需要的信息保存下来,后面使用的时候再取出

// 接口
<?php

namespace App\Service;

interface CommonServiceInterface
{
    public function record($cache);
    public function recover();
    public function clear();
}

// 实现
<?php

namespace App\Service;

class CommonService implements CommonServiceInterface
{
    public $cache;
    public function record($cache)
    {
        $this->cache[] = $cache;
    }

    public function recover()
    {
        print_r($this->cache);
    }

    public function clear()
    {
        $this->cache = [];
    }
}

// 测试
 $common = new CommonService();
        $common->record('获得100金币');
        $common->record('升级29级');
        $common->record('获得极品装备');

        $common->recover();
        $common->clear();
        $common->recover();

// 结果
在这里插入图片描述

17、状态模式

特点:根据不同的状态,执行不同的操作,跟观察者模式类似,区别是状态模式可以自己管理状态的维护,并且更加专注于状态控制,状态控制策略与仲裁者有相似之处

// 状态接口
<?php

namespace App\Service;

interface CommonServiceInterface
{
    function checkState($h);
}

// 状态实现1
<?php

namespace App\Service;

class SideService implements CommonServiceInterface
{
    private $service;
    public function service($service)
    {
        $this->service = $service;
    }

    public function say($word)
    {
        echo 'side状态说你真好看'.'<br>';
    }

    public function checkState($h)
    {
        if ($h>12) {
            $this->service->changeStateService(SurroundingService::class);
        }
    }
}


// 状态接口实现2
<?php

namespace App\Service;

class SurroundingService implements CommonServiceInterface
{
    private $service;
    public function service($service)
    {
        $this->service = $service;
    }

    public function say($word)
    {
        echo 'surrounding状态说你真好看'.'<br>';
    }

    public function checkState($h)
    {
        if ($h<=12) {
            $this->service->changeStateService(SurroundingService::class);
        }
    }
}

// 状态管理类
<?php

namespace App\Service;

class CommonService
{
    public $h;
    public $stateService;

    public function __construct($h)
    {
        $this->h = $h;
        $this->stateService = new SideService();
        $this->stateService->service($this);
    }

    public function changeStateService($class)
    {
        $this->stateService = new $class();

        return $this->stateService;
    }

    public function say()
    {
        // 检测状态
        $this->stateService->checkState($this->h);

        $this->stateService->say('hello world');
    }
}

// 测试
$common = new CommonService(11);
        $common->say();

        $common = new CommonService(13);
        $common->say();

// 结果
在这里插入图片描述

18、享元设计模式

特点:提取出具有相似的基础功能,由管理的类去实现调用,跟策略模式相似,区别是享元更加轻量化

// 功能1
<?php

namespace App\Service;

class SideService
{

    public function out()
    {
        echo 'this is side func<br>';
    }
}

// 功能2
<?php

namespace App\Service;

class SurroundingService
{

    public function out()
   {
       echo 'this is surround func';
   }
}

// 管理类
<?php

namespace App\Service;

class CommonService
{
    public $sideService;
    public $surroundingService;
    public $operate;

    public function __construct($operate)
    {
        $this->sideService = new SideService();

        $this->surroundingService = new SurroundingService();

        $this->operate = $operate;
    }

    public function say()
    {
        // 检测状态

        if (property_exists($this,$this->operate)) {
            $this->{$this->operate}->out();
        } else {
            echo '这是普通输出<br>';
        }

    }
}

// 测试
$common = new CommonService('sideService');
        $common->say();

        $common = new CommonService('notFundService');
        $common->say();

// 结果:
在这里插入图片描述

19、代理模式

特点:借鉴了服务器的代理模式,如果可以处理的,直接走目标服务器,如果处理不了的走代理再转发服务器,实现过滤的效果,跟享元模式类似,区别是代理模式更专注与过滤,而享元更关注于基础通用功能的提取

// 目标服务器类1
<?php

namespace App\Service;

class SideService
{

    public function out()
    {
        echo 'this is side func<br>';
    }
}

// 目标服务器类2
<?php

namespace App\Service;

class SurroundingService
{

    public function out()
   {
       echo 'this is surround func';
   }
}

// 代理类
<?php

namespace App\Service;

class CommonService
{
    public $allowService = ['sideService' => SideService::class, 'surroundingService' => SurroundingService::class];
    public $proxyService = SurroundingService::class;
    public $operate;

    public function __construct($operate)
    {

        $this->operate = $operate;
    }

    public function proxy()
    {
        // 代理
        if ($this->isSupport()) {

            (new $this->allowService[$this->operate])->out();
        } else {

            (new $this->proxyService)->out();
        }
    }

    protected function isSupport()
    {
        return array_key_exists($this->operate, $this->allowService);
    }
}

// 测试
 $common = new CommonService('sideService');
        $common->proxy();

        $common = new CommonService('notFundService');
        $common->proxy();

// 结果
在这里插入图片描述

20、命令模式

特点:把执行过的命令类,保存为history,需要的时候可以复现history存储的命令

// 画笑脸类
<?php

namespace App\Service;

class SideService implements CommonServiceInterface
{

    public function action($className = '')
    {
        echo '😊';
    }
}

// 画玫瑰类
<?php

namespace App\Service;

class SurroundingService implements CommonServiceInterface
{

    public function action($className='')
   {
       echo '🌹';
   }
}

// 画画类
<?php

namespace App\Service;

class CommonService implements CommonServiceInterface
{
    public $history = [];

    public function action($className)
    {
        $obj = new $className();
        $obj->action();
        $reflection = new \ReflectionClass($className);
        $this->add($reflection->getName());
    }

    public function add($className)
    {
        $this->history[] = $className;
    }

    public function clear()
    {
        $this->history = [];
    }

    public function recover()
    {
        foreach ($this->history as $className) {
            (new $className)->action();
        }
    }
}

// 测试
$common = new CommonService();
        $common->action(SideService::class);
        $common->action(SideService::class);
        $common->action(SurroundingService::class);
        $common->action(SurroundingService::class);
        echo '<br>';
        $common->recover();
        echo '<br>';
        $common->clear();
        $common->recover();

// 结果
在这里插入图片描述

21、解释器模式

特点:对自定义语法提供的解释器类,可以把自定义语法解释为原生语法

// 接口
<?php

namespace App\Service;

interface CommonServiceInterface
{
    public function execute($className);
    public function check();
    public function isValid();
}

// 解释器1
<?php

namespace App\Service;

class CommonService implements CommonServiceInterface
{
    public $command = ['SideService'=>SideService::class];
    protected $execute;
    protected $tokenizer;
    public function execute($command)
    {
        $this->execute = $command;
        $this->tokenizer();

        $this->check();
    }


    public function check()
    {

        if ($this->isValid()) {

            echo '执行命令:'.$this->tokenizer[0].(new $this->command[$this->tokenizer[0]]())->execute(array_slice($this->tokenizer,1));

        } else {
            die('命令不合法,支持的命令为:['.join(',',array_keys($this->command)).']');
        }
    }


    public function isValid()
    {
        if ($this->tokenizer) {

            return array_key_exists($this->tokenizer[0],$this->command);
        } else {
            return false;
        }

    }

    public function tokenizer()
    {
        $arr = explode(' ',$this->execute);

        if ($arr) {
             $data = array_filter($arr,function($item){

                return $item != "";
            });
        } else {
            $data = [];
        }

        $this->tokenizer = $data;
    }
}

// 解释器2
<?php

namespace App\Service;

class SideService implements CommonServiceInterface
{

    public $command = ['SurroundingService'=>SurroundingService::class];
    public $fuzzy = 'file';
    public $execute;
    public $check;
    public function execute($command)
    {
        $this->execute = $command;

        return $this->check();
    }

    public function check()
    {
        $valid = $this->isValid();
        if ($valid === true) {

            return ' '.$this->execute[0].' '.(new $this->command[$this->execute[0]]())->execute($this);

        } else if ($valid === false) {

            if ($this->fuzzy) {
                if (count($this->execute)>1) {
                    die('命令不合法,fuzzy命令不支持参数');
                } else {
                    return ' '.$this->execute[0];
                }

            } else {
                die('命令不合法,不支持fuzzy命令');
            }


        } else {
            die('命令不合法,支持的命令为:['.join(",",array_keys($this->command)).'] '.(property_exists($this,'fuzzy')?'或者'.$this->fuzzy:''));
        }
    }


    public function isValid()
    {
        if ($this->execute) {
            return array_key_exists($this->execute[0],$this->command);
        } else {
            return -1;
        }

    }
}

// 解释器3
<?php

namespace App\Service;

class SurroundingService implements CommonServiceInterface
{
    protected $execute;

    public function execute($command)
    {
        $this->execute = $command;

        return $this->check();
    }


    public function check()
    {

        if (isset($this->execute->execute[1])) {

            return ' '.$this->execute->execute[1];
        } else {

            die('命令不合法,'.$this->execute->execute[0].'操作需要参数');
        }

    }


    public function isValid()
    {

    }
}

// 测试
 $common = new CommonService();

        $common->execute('SideService   SurroundingService list');

// 结果
在这里插入图片描述
~ ending ~

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值