Code前端首页关于Code前端联系我们

PHP 软件开发:设计模式 |观察者模式(Observer)分析与应用

terry 2年前 (2023-09-25) 阅读数 59 #后端开发

使用场景

假设项目经理让我们写一个登录界面,咔咔写完了

  • 我们第二天添加统计登录,然后添加代码吧 【观察者结构图】
PHP软件开发:设计模式|观察者模式(Observer)解析与应用

概念

(观察者),首先被观察的必须是角色,但他是【独一无二】的。虽然只有一个“表演者”,但有很多“观众”,即围绕着一个“人”的一群“人”。既然有无数的观察者,我们就需要知道那里有哪些“人”。所以我们需要一个“容器”来存储这些“人”,一个类似于数组的容器,里面存储了所有的观察者。

“演员”(观察者)、一群“观众”(观察者)、“相机”(存储容器)

★【我的PHP进阶学习交流社区“点击”】准备的社区专用材料的管理:来自BAT等优质厂商的高级信息系统(相关学习资料和笔试题)包括但不限于:分布式架构、高扩展性、高性能、高并发、服务器性能调优、TP6、laravel、YII2、Redis、Swoole、Swoft 、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx等诸多数据点,进阶进阶的数据

【观察者模式下角色的主要】

  1. 抽象主题(Subject)角色:主题角色商店对集合中观察对象的所有引用,并且每个主题可以有任意多个观察者。抽象主题提供了用于添加和删除观察者对象的用户界面。
  2. 抽象观察者(观察者)角色:为所有具体观察者定义一个接口,并在观察对象发生变化时自行更新。
  3. 具体主体(ConcreteSubject)角色:将相关状态存储在特定的观察对象中。当特定对象的内部状态发生变化时,会向所有注册的观察者发送通知。具体主体 角色 通常用具体子类来实现。
  4. 具体观察者(ConcretedObserver)角色:保存具体的主体对象,存储其关联状态,并实现抽象观察者角色所需的更新接口,使其自身的状态与对象的状态一致。?我们定义了登录区域,并在最后添加了代码
  5. 第四天,我们在用户登录后推送了该功能,然后将代码添加到了末尾
  6. 第N天,这个UI变得混乱不堪没有人愿意维护它
  7. 我们需要保持项目的高内聚和低连接,这样我们就可以使用观察者模式(不是必须的,根据需求而定)

    [观察模式和其他模式]

    1. 【中介者模型】(Mediator):ChangeManager通过封装复杂的更新语义,充当目标和观察者之间的中介。
    2.【Singleton模式】(单例模式):ChangeManager可以使用Singleton模式来保证其唯一性和全局可用。

  • 第三天,我们定义登录区域,然后添加代码
  • 第四天,我们在用户登录后推送活动,然后添加代码
  • 第N天,这个界面已经很乱了。人们想要保留它,这正在被观察到。然后就有无数的观察者来看他。可以说一群人在注视着一个人。既然有无数的观察者,就必须有一些东西来记录有观察者。那么应该有一个与所有观察者相似的数组。综上,有一个观察者,无数个观察者,一个容器记录

    ★ PHP高级学习交流社区“点击”管理完成 社区独家教材:高级信息系统(相关学习资料和笔试面试题)优质厂家如作为BAT,不限:分布式架构、高扩展、高性能、高并发、服务器性能调优、TP6、laravel、YII2、Redis、Swoole、Swoft、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx等数据点、高级高级信息

    代码示例

    • 界面示例
    // 主题接口
    interface Subject{
        public function register(Observer $observer);
        public function notify();
    }
    // 观察者接口
    interface Observer{
        public function watch();
    }
    复制代码

    主体是观察者,观察者是观众,即观察者被观察的界面被观察者,他现在被观察了,并且然后定义$_observers表,他是存储观众的容器。

    首先实现register方法,用它传递观察,然后添加到数组中,然后实现notify()方法,该方法循环容器数组,执行每个观察者的watch()方法。

    Observer

    // 观察者
    class Cat implements Observer{
         public function watch(){
             echo "Cat watches TV<hr/>";
         }
     }
     class Dog implements Observer{
         public function watch(){
             echo "Dog watches TV<hr/>";
         }
     }
     class People implements Observer{
         public function watch(){
             echo "People watches TV<hr/>";
         }
     }
    复制代码

    这里定义了三个观察者,它们都实现了Observer接口。前面的Subject在循环中调用了每个watcher的watch()方法,所以我们需要实现每个watcher的watch()方法。方法。

    调用

    // 应用实例
    $action=new Action();
    $action->register(new Cat());
    $action->register(new People());
    $action->register(new Dog());
    $action->notify();
    复制代码

    首先,新的被观察对象,执行其register()方法,将每个观察者放入容器队列中,最后执行notify()方法,提示所有观察者执行自己的方法。

    php 有自己内置的观察者模式

    php 有自己内置的观察者模式

    • splSubject 接口 - 被观察者
    • ObServer 接口 - 观察者
    • splobjetorage 对象 - 容器

    First of all,我们有登录类

    class user{
    
      public function login()
      {
          echo '登录完毕'
      }
    复制代码

    ,让他实现splsubject接口,成为观察者。

    • 首先让它在构造函数中创建一个新的SplObjectStorag()对象,并将其赋值给属性以供后续调用。
    • 实现attach()方法来注册观察者
    • 实现detach()方法来删除观察者
    • 实现notify()方法,该方法用于循环容器并调用每个观察者的update方法。 (需要更新)
    • Rewind方法将容器指针返回到开头,valid方法检测容器遍历是否结束并返回一个Boolean,当前方法是获取当前观察者,下一个方法是移动将指针向后移动一位
    • 编辑login()方法并在其中调用notify()来通知观察者事件结束。

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门