设计模式-观察者模式

观察者模式为您提供了避免组件之间紧密耦合的另一种方法。该模式非常简单:观察者模式是一种事件系统,意味着这一模式允许某个类观察另一个类的状态,当被观察的类状态发生改变的时候,观察类可以收到通知并且做出相应的动作。

观察者模式定义对象的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。

设计原则

在观察者模式中,会改变的是主题的状态以及观察者的数目,用这个模式,你可以改变依赖于主题状态的对象,却不必改变主题 -- 找出程序中会变化的方面,然后将其和固定不变的方面相分离。

主题和观察者都使用接口:观察者利用主题的接口向主题注册而主题利用观察者接口通知观察者。这样可以让两者之间运作正常,又同时具有松耦合的优点 ——针对接口编程,而不针对实现编程。

观察者模式利用“组合”将许多观察者组合进主题中。对象(观察者——主题)之间的这种关系不是通过继承产生的,而是在运行时利用组合的方式产生的。 ——多用组合,少用继承。

从面相对象的角度来看,主题提供注册和通知的接口,观察者提供自身操作的接口。(这些观察者拥有一个同一个接口)观察者利用主题的接口向主题注册,而主题利用观察者接口通知观察者。观察者模式更多体现了两个独立的类,利用接口完成一件原本很复杂的事情。不利用主题类的话,我们就需要不断循环创建实例,执行操作。而现在只需要创建实例即可,执行操作只需要调用一次通知的方法即可。

/**
 * 观察者模式
 */
class Paper{ /*主题*/
    private $_observers = array();

    public function register($sub){ /*注册观察者*/
        $this->_observers[] = $sub;
    }
     
    public function trigger(){  /*外部统一访问*/
        if(!empty($this->_observers)){
            foreach($this->_observers as $observer){
                $observer->update();
            }
        }
    }
}
 
/**
 * 观察者要实现的接口
 */
interface Observerable{
    public function update();
}
 
class Subscriber implements Observerable{
    public function update(){
        echo "Callback\n";
    }
}

下面是测试代码:

/*测试*/
$paper = new Paper();
$paper->register(new Subscriber());
//$paper->register(new Subscriber1());
//$paper->register(new Subscriber2());
$paper->trigger();

当新对象要填入的时候,只需要在主题(又叫可观察者)中进行注册(注册方式很多,你也可以在构造的时候,或者框架访问的接口中进行注册),然后实现代码直接在新对象的接口中进行。这降低了主题对象和观察者对象的耦合度。

场景:在一个事件发生后,要执行一连串更新操作,传统的编程方式就是在事件的代码后面直接加入处理逻辑,当更新的逻辑增多后,代码就会变得难以维护。这种方式是耦合的、侵入式的,增加新的逻辑需要改变事件主题的代码。而观察者模式实现了低耦合、非侵入式的通知与更新机制。

posted @ 2019-03-15 10:57  让我们荡起双桨!  阅读(126)  评论(0编辑  收藏  举报