PHP实现观察者模式

【特点】
观察者模式定义对象的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新!
观察者模式利用“组合”将许多观察者组合进主题中。对象(观察者——主题)之间的这种关系不是通过继承产生的,而是在运行时利用组合的方式产生的。 ——多用组合,少用继承!

【观察者模式的优点和缺点】
观察者模式的优点:
1、观察者和主题之间的耦合度较小;
2、支持广播通信;

观察者模式的缺点:
1、由于观察者并不知道其它观察者的存在,它可能对改变目标的最终代价一无所知。这可能会引起意外的更新。

【观察者模式适用场景】
1、当一个抽象模型有两个方面,其中一个方面依赖于另一个方面。
2、当对一个对象的改变需要同时改变其它对象,而不知道具体有多少个对象待改变。
3、当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换句话说,你不希望这些对象是紧密耦合的。

<?php
/**
 * 抽象主题角色
 */
interface Subject
{

    /**
     * 增加一个新的观察者对象
     * @param Observer $observer
     */
    public function attach(Observer $observer);

    /**
     * 删除一个已注册过的观察者对象
     * @param Observer $observer
     */
    public function detach(Observer $observer);

    /**
     * 通知所有注册过的观察者对象
     */
    public function notifyObservers();
}

/**
 * 具体主题角色
 */
class ConcreteSubject implements Subject
{

    private $_observers;

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

    /**
     * 增加一个新的观察者对象
     * @param Observer $observer
     */
    public function attach(Observer $observer)
    {
        return array_push($this->_observers, $observer);
    }

    /**
     * 删除一个已注册过的观察者对象
     * @param Observer $observer
     */
    public function detach(Observer $observer)
    {
        $index = array_search($observer, $this->_observers);
        if ($index === FALSE || ! array_key_exists($index, $this->_observers)) {
            return FALSE;
        }

        unset($this->_observers[$index]);
        return TRUE;
    }

    /**
     * 通知所有注册过的观察者对象
     */
    public function notifyObservers()
    {
        if (!is_array($this->_observers)) {
            return FALSE;
        }

        foreach ($this->_observers as $observer) {
            $observer->update();
        }

        return TRUE;
    }

}

/**
 * 抽象观察者角色
 */
interface Observer
{

    /**
     * 更新方法
     */
    public function update();
}

class ConcreteObserver implements Observer
{

    /**
     * 观察者的名称
     * @var <type>
     */
    private $_name;

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

    /**
     * 更新方法
     */
    public function update()
    {
        echo 'Observer', $this->_name, ' has notified.<br />';
    }

}

/**
 * 客户端
 */
class Client
{

    /**
     * Main program.
     */
    public static function main()
    {
        $subject = new ConcreteSubject();

        /* 添加第一个观察者 */
        $observer1 = new ConcreteObserver('Martin');
        $subject->attach($observer1);

        echo '<br /> The First notify:<br />';
        $subject->notifyObservers();

        /* 添加第二个观察者 */
        $observer2 = new ConcreteObserver('phppan');
        $subject->attach($observer2);

        echo '<br /> The Second notify:<br />';
        $subject->notifyObservers();

        /* 删除第一个观察者 */
        $subject->detach($observer1);

        echo '<br /> The Third notify:<br />';
        $subject->notifyObservers();
    }

}

Client::main();
?>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值