php设计模式(二十一)观察者模式

在业务开发过程中多个功能会互相依赖;
如果我们想在一个对象发生变化后通知和它有关联的类;
比如说你做了某件事后希望可以使用邮件和短信发送通知;
这时候就比较适合使用观察者模式了;
不过 php 官方已经提供了 SplObserverSplSubject
因此这又是一篇为了设计模式而写设计模式的文章;

结构

SubjectAbstract: Subject 抽象类 示例中指 SubjectAbstract.php;
Subject: 具体的类 示例中指 Subject.php;
Observer: Observer接口 示例中指 Observer.php;
ConcreteObserver: 具体的 Observer 示例中指 EmailObserver.php 和 SMSObserver.php ;

示例

SubjectAbstract.php

<?php

namespace Baijunyao\DesignPatterns\Observer;

/**
 * Observer 抽象类
 *
 * @package Baijunyao\DesignPatterns\Observer
 */
abstract class SubjectAbstract
{
    /**
     * @var array
     */
    private $observers = [];

    /**
     * @param \Baijunyao\DesignPatterns\Observer\Observer $observer
     */
    public function attach(Observer $observer)
    {
        $this->observers[] = $observer;
    }

    /**
     * 通知
     */
    public function notify()
    {
        foreach ($this->observers as $k => $v) {
            $v->update();
        }
    }
}

Subject.php

<?php

namespace Baijunyao\DesignPatterns\Observer;

/**
 * 具体 Subject
 *
 * @package Baijunyao\DesignPatterns\Observer
 */
class Subject extends SubjectAbstract
{
    public function publish()
    {
        echo '我做了某事<br>';
        $this->notify();
    }
}

Observer.php

<?php

namespace Baijunyao\DesignPatterns\Observer;

/**
 * Observer 接口
 *
 * @package Baijunyao\DesignPatterns\Observer
 */
interface Observer
{
    /**
     * @return mixed
     */
    public function update();
}

EmailObserver.php

<?php

namespace Baijunyao\DesignPatterns\Observer;

/**
 * 发邮件
 *
 * @package Baijunyao\DesignPatterns\Observer
 */
class EmailObserver implements Observer
{
    /**
     * 执行操作
     */
    public function update()
    {
        echo '发送邮件昭告天下<br>';
    }
}

SMSObserver.php

<?php

namespace Baijunyao\DesignPatterns\Observer;

/**
 * 发短信
 *
 * @package Baijunyao\DesignPatterns\Observer
 */
class SMSObserver implements Observer
{
    /**
     * 执行操作
     */
    public function update()
    {
        echo '发送短信昭告天下<br>';
    }
}

index.php

<?php

namespace Baijunyao\DesignPatterns\Observer;

require __DIR__.'/../vendor/autoload.php';

/**
 * 客户端
 *
 * Class Client
 * @package Baijunyao\DesignPatterns\Observer
 */
class Client
{
    /**
     * 运行
     */
    public function run()
    {
        $emailObserver = new EmailObserver();
        $SMSObserver = new SMSObserver();
        $subject = new Subject();

        $subject->attach($emailObserver);
        $subject->attach($SMSObserver);
        $subject->publish();
    }
}

$client = new Client();
$client->run();

当然正如开始所说;
在世界上最好的语言中;
根本不需要这么麻烦;
直接使用实现 SplObserverSplSubject 即可;

github示例:https://github.com/baijunyao/design-patterns/tree/master/Observer

白俊遥博客
请先登录后发表评论
  • latest comments
  • 总共7条评论
白俊遥博客

苦笑 :如何传参呢,每次发送的邮件地址不一样呢

2019-03-27 11:25:51 回复

白俊遥博客

zhaoqinghuan :期待大佬的更新,持续关注您。

2019-01-06 15:02:53 回复

白俊遥博客

517 :这篇看完了,一共23个模型,还有两个,等待中。。。

2018-12-24 23:58:29 回复

白俊遥博客

Running :大神,问一个比较久远的问题,后台登录验证码点击更换,一样的代码[点击更换]为什么你的请求是这样的 http://develop.blog.com/index.php/Admin/Login/showVerify/0.48932164379284415;而我的请求确实这样的 http://develop.myblog.com/index.php/Admin/Login/showVerify.html/0.5796237576970569;多了一个.html;导致请求404;方便解惑吗?当把‘/’换成‘?’,请求变成了这样 http://develop.myblog.com/index.php/Admin/Login/showVerify.html?0.5565901631192529 ;但是可以请求成功;如果可以的话请解惑,谢谢谢谢!!

2018-12-11 11:37:47 回复

白俊遥博客

花舞千魂殇 :顺带能问下 博主最后一张图中使用的是什么软件

2018-12-10 00:15:52 回复

白俊遥博客

花舞千魂殇 :学习了  SplObserver 和 SplSubject 真心省事

2018-12-10 00:06:39 回复

白俊遥博客

Gxy :-

2018-12-03 14:26:07 回复