zoukankan      html  css  js  c++  java
  • PHP设计模式-观察者模式

    1、概念:

      其实观察者模式这是一种较为容易去理解的一种模式吧,它是一种事件系统,意味 着这一模式允许某个类观察另一个类的状态,当被观察的类状态发生改变的时候,观察类可以收到通知并且做出相应的动作;观察者模式为您提供了避免组件之间
    紧密耦合的另一种方法

      观察者模式(Observer),当一个对象的状态发生改变时,依赖他的对象会全部收到通知,并自动更新。

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

    2、关键点:   

      1.被观察者->追加观察者;->一处观察者;->满足条件时通知观察者;->观察条件
      2.观察者 ->接受观察方法

    3、优缺点:   

      优点:1.观察者和主题之间的耦合度较小;2.支持广播通信;
      缺点:由于观察者并不知道其它观察者的存在,它可能对改变目标的最终代价一无所知。这可能会引起意外的更新

    4、观察者模式在PHP中的应用场合:在web开发中观察者应用的方面很多  

      典型的:用户注册(验证邮件,用户信息激活),购物网站下单时邮件/短信通知等

    5、php内部的支持  

      SplSubject 接口,它代表着被观察的对象,
    其结构:

    php内部类,SplSubject
    interface
    SplSubject {   public function attach(SplObserver $observer);   public function detach(SplObserver $observer);   public function notify(); }

    SplObserver 接口,它代表着充当观察者的对象,
    其结构:

    
    
    php内部类,SplObserver
    interface SplObserver
    { 
        public function update(SplSubject $subject);
    }

    使用PHP内部类例子:

    class MyObserver1 implements SplObserver {
        public function update(SplSubject $subject) {
            echo __CLASS__ . ' - ' . $subject->getName();
        }
    }
    
    class MyObserver2 implements SplObserver {
        public function update(SplSubject $subject) {
            echo __CLASS__ . ' - ' . $subject->getName();
        }
    }
    
    class MySubject implements SplSubject {
        private $_observers;
        private $_name;
    
        public function __construct($name) {
            $this->_observers = new SplObjectStorage();
            $this->_name = $name;
        }
    
        public function attach(SplObserver $observer) {
            $this->_observers->attach($observer);
        }
    
        public function detach(SplObserver $observer) {
            $this->_observers->detach($observer);
        }
    
        public function notify() {
            foreach ($this->_observers as $observer) {
                $observer->update($this);
            }
        }
    
        public function getName() {
            return $this->_name;
        }
    }
    
    $observer1 = new MyObserver1();
    $observer2 = new MyObserver2();
    
    $subject = new MySubject("test");
    
    $subject->attach($observer1);
    $subject->attach($observer2);
    $subject->notify();

    自己自定义类例子:

    #===================定义观察者、被观察者接口============
    /**
     *
     * 观察者接口(通知接口)
     *
     */
    interface ITicketObserver //观察者接口
    {
      function onBuyTicketOver($sender, $args); //得到通知后调用的方法
    }
    /**
     *
     * 主题接口
     *
     */
    interface ITicketObservable //被观察对象接口
    {
      function addObserver($observer); //提供注册观察者方法
    }
    #====================主题类实现========================
    /**
     *
     * 主题类(购票)
     *
     */
    class HipiaoBuy implements ITicketObservable { //实现主题接口(被观察者)
      private $_observers = array (); //通知数组(观察者)
      public function buyTicket($ticket) //购票核心类,处理购票流程
    {
        // TODO 购票逻辑
        //循环通知,调用其onBuyTicketOver实现不同业务逻辑
        foreach ( $this->_observers as $obs )
          $obs->onBuyTicketOver ( $this, $ticket ); //$this 可用来获取主题类句柄,在通知中使用
      }
      //添加通知
      public function addObserver($observer) //添加N个通知
    {
        $this->_observers [] = $observer;
      }
    }
    #=========================定义多个通知====================
    //短信日志通知
    class HipiaoMSM implements ITicketObserver {
      public function onBuyTicketOver($sender, $ticket) {
        echo (date ( 'Y-m-d H:i:s' ) . " 短信日志记录:购票成功:$ticket<br>");
      }
    }
    //文本日志通知
    class HipiaoTxt implements ITicketObserver {
      public function onBuyTicketOver($sender, $ticket) {
        echo (date ( 'Y-m-d H:i:s' ) . " 文本日志记录:购票成功:$ticket<br>");
      }
    }
    //抵扣卷赠送通知
    class HipiaoDiKou implements ITicketObserver {
      public function onBuyTicketOver($sender, $ticket) {
        echo (date ( 'Y-m-d H:i:s' ) . " 赠送抵扣卷:购票成功:$ticket 赠送10元抵扣卷1张。<br>");
      }
    }
    #============================用户购票====================
    $buy = new HipiaoBuy ();
    $buy->addObserver ( new HipiaoMSM () ); //根据不同业务逻辑加入各种通知
    $buy->addObserver ( new HipiaoTxt () );
    $buy->addObserver ( new HipiaoDiKou () );
    //购票
    $buy->buyTicket ( "一排一号" );

    注意:

    观察者模式典型实现方式:
    1、定义2个接口:观察者(通知)接口、被观察者(主题)接口,可直接使用PHP内部类
    2、定义2个类,观察者对象实现观察者接口、主题类实现被观者接口
    3、主题类注册自己需要通知的观察者
    4、主题类某个业务逻辑发生时通知观察者对象,每个观察者执行自己的业务逻辑。

  • 相关阅读:
    TCP与UDP的差别以及TCP三次握手、四次挥手
    MAC帧格式、IPV4数据报格式、TCP报文格式、UDP数据报格式
    维特比算法(Viterbi)-实例讲解(暴力破解+代码实现)
    对ajax的理解
    get与post两种方式的优缺点
    什么是Ajax和JSON,它们的优缺点
    浅谈一下如何避免用户多次点击造成的多次请求
    ajax是什么?
    同步和异步的区别?
    如何解决跨域问题
  • 原文地址:https://www.cnblogs.com/zhangzhijian/p/14624641.html
Copyright © 2011-2022 走看看