zoukankan      html  css  js  c++  java
  • 设计模式

    简介

    场景

    如果想实时跟踪某个对象的状态(例如,对于负责下载的对象,想实时跟踪下载进度),有两种方法:

    • 定时轮询:定时访问目标对象的接口,获取其当前状态
    • 主动通知:在目标对象发生变化时,主动通知需要知道这个变化的对象

    模式定义

    观察者模式(Observer Pattern):定义对象间的一种一对多依赖关系,使得当一个对象状态发生改变时,所有依赖它的对象将自动得到通知和更新。

    观察者模式又叫做发布-订阅(Publish/Subscribe)模式。

    模式特点

    观察者模式包含四个角色,发生改变的对象称为观察目标,而被通知的对象称为观察者,一个观察目标可以对应多个观察者,而且这些观察者之间没有相互联系:

    • Subject:观察对象
    • ConcreteSubject:具体观察对象
    • Observer:观察者
    • ConcreteObserver:具体观察者

    这里写图片描述

    优缺点

    • 观察者模式可以实现表示层和数据逻辑层的分离,并定义了稳定的消息更新传递机制,抽象了更新接口,使得可以有各种各样不同的表示层作为具体观察者角色。
    • 观察者模式在观察目标和观察者之间建立松耦合,可以独立改变目标或观察者
    • 观察者自己觉得是否订阅通知,目标对象对此一无所知
    • 新增监控要求时,大型的单体设计不能很好地扩展

    PHP 代码示例

    AbstractObserver 是观察者抽象类,其中定义了用来被观察目标调用的 update() 方法。AbstractSubject 是观察目标抽象类,其中定义了用来添加观察者的 attach() 方法,用来删除观察者的 detach() 方法,用于通知所有观察者的 notify() 方法。

    <?php
    
    abstract class AbstractObserver {
        abstract function update(AbstractSubject $subject_in);
    }
    
    abstract class AbstractSubject {
        abstract function attach(AbstractObserver $observer_in);
        abstract function detach(AbstractObserver $observer_in);
        abstract function notify();
    }
    
    class PatternObserver extends AbstractObserver {
        public function update(AbstractSubject $subject) {
          writeln(' new favorite patterns: '.$subject->getFavorites());    
        }
    }
    
    class PatternSubject extends AbstractSubject {
        private $favoritePatterns = NULL;
        private $observers = array();
        function attach(AbstractObserver $observer_in) {
          $this->observers[] = $observer_in;
        }
        function detach(AbstractObserver $observer_in) {
          //$key = array_search($observer_in, $this->observers);
          foreach($this->observers as $okey => $oval) {
            if ($oval == $observer_in) { 
              unset($this->observers[$okey]);
            }
          }
        }
        function notify() {
          foreach($this->observers as $obs) {
            $obs->update($this);
          }
        }
        function updateFavorites($newFavorites) {
          $this->favorites = $newFavorites;
          $this->notify();
        }
        function getFavorites() {
          return $this->favorites;
        }
    }
    
    function writeln($line_in) {
        echo $line_in."<br/>".PHP_EOL;
    }
    
      writeln('BEGIN TESTING OBSERVER PATTERN');
      writeln('');
    
      $subject= new PatternSubject();
      $observer= new PatternObserver();
      $subject->attach($observer);
      $subject->updateFavorites('abstract factory, decorator, visitor');
      $subject->updateFavorites('abstract factory, observer, decorator');
      $subject->detach($observer);
      $subject->updateFavorites('abstract factory, observer, paisley');
    
      writeln('END TESTING OBSERVER PATTERN');
  • 相关阅读:
    45
    布里斯班初体验
    走出你的舒适区
    Homebrew- MAC上的包管理利器
    Java经典类库-Guava中的函数式编程讲解
    使用WebDriver遇到的那些坑
    CheckStyle, 强制你遵循编码规范
    利用php的register_shutdown_function来记录php的输出日志
    PHP-redis中文文档
    php中set_time_limit()函数运用
  • 原文地址:https://www.cnblogs.com/kika/p/10851573.html
Copyright © 2011-2022 走看看