资讯专栏INFORMATION COLUMN

PHP设计模式之观察者模式

hizengzeng / 1200人阅读

摘要:观察者模式解决的问题在我们的开发过程中,应该都或多或少的碰到过改动其中一部分代码会引起其他一连串改变的问题,显然想要完全避免这种情况不太可能,但我们也应答尽量减少对其他组件的依赖,而观察者模式就是为了解决这个问题。

观察者模式解决的问题

在我们的开发过程中,应该都或多或少的碰到过改动其中一部分代码会引起其他一连串改变的问题,显然想要完全避免这种情况不太可能,但我们也应答尽量减少对其他组件的依赖,而观察者模式就是为了解决这个问题。

举个例子来说,我们有一个帖子对象,代码如下:

class Post
{

    protected $_userid = null;
    protected $_ip = null;
    protected $_content = null;


    function __construct()
    {
        // ...
    }
    // 发帖方法
    public function addPost()
    {
        
        // ...    发帖逻辑
    }
}

在上面是一个普通的帖子对象,随着发帖量和访问量越来越大,运营们开始不干了,公司也经常会接到投诉电话,说我们的网站有许多敏感内容和垃圾广告,因此我们需要做内容审核:首先是对用户的审核,一些黑名单用户应该被禁止发帖;二是对IP的审核;三是对内容敏感词的审核。因此我们的代码就成了如下的样子:

class Post
{

    protected $_userid = null;
    protected $_ip = null;
    protected $_content = null;


    function __construct()
    {
        
    }

    public function addPost()
    {
        if (!Postscan::checkUserid($tihs->_userid)) {
            return false;
        }
        if (!Postscan::ipUserid($tihs->_ip)) {
            return false;
        }
        if (!Postscan::checkContent($tihs->_content)) {
            return false;
        }

        // ...    
    }
}

随着需要审核的字段越来越多,addPost方法变得越来越长,发布对象被也只能紧紧的被嵌入到该系统中。

观察者模式的实现

观察者模式的核心是把观察者从主体中分离开来,当主体知道事件发生时,观察需要被通知到,同时我们也不想把主体和观察者之间的关系写死,于是我们来修改下我们上面的代码:

//主体必须实现的接口
interface Observable {
    public function attach(Observer $observer);
    public function detach(Observer $observer);
    public function notify();
}
//观察者必须实现的接口
interface Observer {
    public function do(Observable $subject);
}

class Post implements Observable
{
    protected $_userid = null;
    protected $_ip = null;
    protected $_content = null;

    protected $_observerlist = array();

    function __construct()
    {
        
    }

    public function attach(Observer $observer)
    {
        $this->_observerlist[] = $observer;
    }

    public function detach(Observer $observer)
    {
        foreach ($this->_observerlist as $key => $value) {
            if ($observer === $value) {
                unset($this->_observerlist[$key])
            }
        }
    }

    public function notify()
    {
        foreach ($this->_observerlist as $value) {
            if (!$value->do($this)) {
                return false;
            }
        }
        return true;
    }

    public function addPost()
    {
        if (!$this->notify()) {
            return false;
        }
        
        // ...    
    }
}

通过上面的代码,我们可以再很容易的加入审核规则。

SPL代码

观察者模式是一个很常见和常用的设计模式,以至于SPL扩展已经为我们封装好了对应的类和方法,下面的代码是根据SPL提供的3个元素:SplObserver,SplSubject,SplObjectStorage来实现的代码

class Post implements SplSubject
{

    protected $_userid = null;
    protected $_ip = null;
    protected $_content = null;

    protected $_storage = new SplObjectStorage();

    function __construct()
    {
        
    }

    public function attach(SplObject $observer)
    {
        $this->_storage->attach($observer);
    }

    public function detach(SplObject $observer)
    {
        $this->_storage->detach($observer);
    }

    public function notify()
    {
        foreach ($this->_storage as $value) {
            if (!$value->update($this)) {
                return false;
            }
        }
        return true;
    }

    public function addPost()
    {
        if (!$this->notify()) {
            return false;
        }

        // ...    
    }
}

很简单吧,最重要的是理解,在这个例子中,我们把一些审核的方法从帖子类中剥离了开来,而且该帖子对象也可以用来作为其他的发布类型。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/21363.html

相关文章

  • PHP设计模式察者模式

    摘要:概念观察者模式属于行为模式,是定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动刷新。观察者模式符合接口隔离原则,实现了对象之间的松散耦合。 概念 观察者模式属于行为模式,是定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动刷新。 当一个对象状态发生改变后,会影响到其他几个对象的改变,这...

    phpmatt 评论0 收藏0
  • php设计模式

    摘要:我们今天也来做一个万能遥控器设计模式适配器模式将一个类的接口转换成客户希望的另外一个接口。今天要介绍的仍然是创建型设计模式的一种建造者模式。设计模式的理论知识固然重要,但 计算机程序的思维逻辑 (54) - 剖析 Collections - 设计模式 上节我们提到,类 Collections 中大概有两类功能,第一类是对容器接口对象进行操作,第二类是返回一个容器接口对象,上节我们介绍了...

    Dionysus_go 评论0 收藏0
  • php设计模式

    摘要:我们今天也来做一个万能遥控器设计模式适配器模式将一个类的接口转换成客户希望的另外一个接口。今天要介绍的仍然是创建型设计模式的一种建造者模式。设计模式的理论知识固然重要,但 计算机程序的思维逻辑 (54) - 剖析 Collections - 设计模式 上节我们提到,类 Collections 中大概有两类功能,第一类是对容器接口对象进行操作,第二类是返回一个容器接口对象,上节我们介绍了...

    vspiders 评论0 收藏0
  • PHP面试常考设计模式——建造者模式

    摘要:你好,是我琉忆,程序员面试笔试系列图书的作者。建造者模式介绍建造者模式又名生成器模式,是一种对象构建模式。表示被构造的复杂对象。创建该产品的内部表示并定义它的装配过程。 你好,是我琉忆,PHP程序员面试笔试系列图书的作者。 本周(2019.3.11至3.15)的一三五更新的文章如下: 周一:PHP面试常考之设计模式——工厂模式周三:PHP面试常考之设计模式——建造者模式周五:PHP面...

    alexnevsky 评论0 收藏0
  • php面向对象设计模式 察者模式

    摘要:最近在学的设计模式,看到了观察者模式,在此写下一点理解问题假如一个小贩,他把产品的价格提升了,不同的消费者会对此产生不同的反应。 最近在学php 的设计模式, 看到了观察者模式,在此写下一点理解: 问题: 假如一个小贩, 他把产品的价格提升了, 不同的消费者会对此产生不同的反应。一般的编程模式无非是获取提升的价格,然后获取所有的消费者,再循环每个消费者, 不同的消费者根据价格涨幅...

    genedna 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<