美文网首页PHP经验分享PHP开发
【设计模式】之工厂模式、单例模式、观察者模式、策略模式(PHP)

【设计模式】之工厂模式、单例模式、观察者模式、策略模式(PHP)

作者: Bryanz | 来源:发表于2022-02-06 13:15 被阅读0次

设计模式是一套被反复使用,代码设计经验的总结,它的主要作用是提升代码的复用性扩展性可靠性,本文主要介绍常见的几种设计模式:工厂模式单例模式观察者模式策略模式

1.工厂模式:
工厂模式是创建型设计模式,它的实现方式是:定义抽象接口,根据产品类具体实现接口,通过工厂类管理具体产品的对象创建;体现的原则是面向接口编程,而不是面向实现编程,这样可以提高代码的扩展性。下面举例分析。

1.1.不使用工厂模式

class Cal
{
    public function calculate($a, $b, $operator)
    {
        switch ($operator) {
            case '+':
                $result = $a + $b;
                break;
            case '-':
                $result = $a - $b;
                break;
            case '*':
                $result = $a * $b;
                break;
            default:
                $result = $a + $b;
        }

        return $result;
    }
}

这种方式看起来没有问题,但是程序的扩展性并不好:假如要加很多个其他计算功能(开方、乘方、对数、三角函数等),则只能在case中继续堆砌代码,这么做的坏处是所有计算类都高度耦合在一起,如果新加的若干个计算类中有一处代码出现问题,则其他计算类都无法使用,同时程序的执行效率也大大降低

2.1.使用工厂模式
为了解决上述问题,降低各个具体类(以计算类为例)的耦合性,提升程序的可扩展性,工厂模式就应运而生,示例代码如下:

//1.计算类的抽象接口
interface CalC
{
    public function getTwoVal($a, $b);
}

//2.面向接口编程,通过实现接口来扩展具体的功能类
class AddC implements CalC
{
    public function getTwoVal($a, $b)
    {
        return $a + $b;
    }
}

class SubC implements CalC
{

    public function getTwoVal($a, $b)
    {
        return $a - $b;
    }
}

class MultiplyC implements CalC
{
    public function getTwoVal($a, $b)
    {
        return $a * $b;
    }
}

//3.工厂类管理具体计算类的创建
class Factory
{
    public static function getObj($operator)
    {
        switch ($operator) {
            case '+':
                $cal = new AddC();
                break;
            case '-':
                $cal = new SubC();
                break;
            case '*':
                $cal = new MultiplyC();
                break;
            default:
                $cal = new AddC();
        }
        return $cal;
    }
}
//使用
$add = Factory::getObj('+');
$res = $add->getTwoVal(5, 2);
echo $res;

通过上述代码可以看到,各个具体计算类的只有自己的相关代码而不包含其他代码,计算类间的耦合性大大降低,利于整个计算功能的扩展。

2.单例模式:
单例模式应该是最简单的设计模式了,同时也非常常见,它的核心思想是只实例化一个对象供全局使用,从而减少内存开销节省系统资源

代码示例:

//2.单例模式,三私一公两静态
class Db
{
    private static $instance;

    private function __construct()
    {
        //内部初始化
    }

    private function __clone()
    {
        //禁止克隆
    }

    //开放单一入口
    public static function getDb()
    {
        //判断实例是否已存在
        if (!(self::$instance instanceof self)) {
            self::$instance = new Db();
        }
        return self::$instance;
    }
}
//测试单例
$db = Db::getDb();
$db1 = Db::getDb();
$res = ($db === $db1);
var_dump($res);

3.观察者模式:
观察者模式属于行为型设计模式,常用于存在一对多关系时:当一个对象发生变更操作时,会自动通知其依赖对象。具体实现方式:将一个类设置为可被观察(实现接口),接着它可以注册观察者类(实现观察者类接口),当前类发生操作变化时可通知观察者类。从而实现观察和被观察者业务逻辑的松散耦合

代码示例

interface Observer
{
    //观察者的方法
    function onChanges($sender, $args);
}

interface Observable
{
    //注册观察者
    function addObserver($observer);
}


class UserList implements Observable
{
    private $observers;

    //可观察的类,添加其观察者
    public function addObserver($observer)
    {
        $this->observers[] = $observer;
    }

    //执行方法,并通知观察者
    public function addCustomer($name)
    {
        foreach ($this->observers as $observer) {
            $observer->onChanges($this, $name);//通知观察者,传递参数和发送人信息
        }
    }
}

class UserListLogger implements Observer
{
    //观察者接受参数,并执行操作
    function onChanges($sender, $args)
    {
        echo "add {$args} to user_list" . PHP_EOL;
    }
}

//使用
$logger = new UserListLogger();//观察类

$userList = new UserList();//可观察类
$userList->addObserver($logger);//添加观察类
$userList->addCustomer('Bryan');//执行动作

观察者的使用场景很多,比如用户注册后发送邮件通知管理员和用户,我们可以将注册逻辑写到可观察类函数中,将发送邮件写到观察者类函数中,这样的好处是将发送邮件逻辑和注册逻辑实现松散耦合注册逻辑的修改不会影响发送邮件逻辑。再比如,用户下单购买商品时,可以在下单成功后通知其观察者,各个观察者分别实现购买记录写入日志、发送短信、送兑换券积分等业务逻辑

4.策略模式
策略模式是行为型设计模式,它可以将一个类的行为方法在运行时进行更改,避免大量使用if-else语句带来的复杂度以及维护成本。

代码示例

interface CalStrategy
{
    function getVal($a, $b);
}

class AddStrategy implements CalStrategy
{
    function getVal($a, $b)
    {
        return $a + $b;
    }
}

class SubStrategy implements CalStrategy
{
    function getVal($a, $b)
    {
        return $a - $b;
    }
}

class MultiplyStrategy implements CalStrategy
{
    function getVal($a, $b)
    {
        return $a * $b;
    }
}

class CalContext
{
    private $strategy;

    //初始化策略
    public function __construct(CalStrategy $strategy)
    {
        $this->strategy = $strategy;
    }

    //用于策略变更
    public function setStrategy(CalStrategy $strategy)
    {
        $this->strategy = $strategy;
    }

    public function getVal($a, $b)
    {
        return $this->strategy->getVal($a, $b);
    }
}

//使用
$calContext = new CalContext(new AddStrategy());//初始化策略
$addResult = $calContext->getVal(5, 10);
echo $addResult . PHP_EOL;

$calContext->setStrategy(new MultiplyStrategy());//变更策略
$mulResult = $calContext->getVal(5, 10);
echo $mulResult . PHP_EOL;

上述代码的例子仍然是工厂设计模式的例子-计算类。可以看到,工厂模式和策略模式都可以实现这种功能,区别在于:工厂模式是类的统一管理,关注的是实例的创建,属于创建型设计模式;而策略模式接受已经创建好的实例,实现不同的行为(变更策略),属于行为型设计模式。

相关文章

  • iOS知识点总结

    一、设计模式:MVC模式、单例模式、观察者模式、MVVM模式、工厂模式、代理模式、策略模式、适配器模式、模板模式、...

  • PHP-浅谈单例模式和工厂模式

    PHP中常用的设计模式有单例模式、工厂模式(简单工厂模式、工厂方法模式和抽象工厂方法模式)、适配模式、策略模式。 ...

  • iOS开发中的几种设计模式

    目前常用的几种设计模式:代理模式、观察者模式、MVC模式、单例模式、策略模式、工厂模式、MVVM (一)代理 场景...

  • iOS开发中的几种设计模式

    目前常用的几种设计模式:代理模式、观察者模式、MVC模式、单例模式、策略模式、工厂模式、MVVM (一)代理 场景...

  • 2020-09-29

    目前常用的几种设计模式:代理模式、观察者模式、MVC模式、单例模式、策略模式、工厂模式、MVVM (一)代理 场景...

  • (IOS)设计模式

    目前常用的几种设计模式:代理模式、观察者模式、MVC模式、单例模式、策略模式、工厂模式、MVVM (一)代理 场景...

  • php高级面试准备

    基础知识 设计模式 Factory工厂模式 Single单例模式 注册模式 适配器模式 策略模式 观察者模式 装饰...

  • iOS设计模式

    设计模式:MVC模式、单例模式、观察者模式、工厂模式、代理模式、策略模式、适配器模式、模版模式、外观模式、创建模式...

  • 设计模式

    单例模式模式工厂模式模式策略者模式适配器模式观察者模式 单例模式 php的应用主要在于数据库应用: 一个应用中会存...

  • ios 开发模式

    目前常用的几种设计模式:代理模式、观察者模式、MVC模式、单例模式、策略模式、工厂模式、MVVM 1.代理 场景:...

网友评论

    本文标题:【设计模式】之工厂模式、单例模式、观察者模式、策略模式(PHP)

    本文链接:https://www.haomeiwen.com/subject/setukrtx.html