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

    一、定义:

      观察者模式(又被称为发布-订阅(Publish/Subscribe)模式,属于行为型模式的一种,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态变化时,会通知所有的观察者对象,使他们能够自动更新自己。

    二、观察者模式中需要如下几种角色

       1、Subject抽象主题(抽象被观察者),主要提供对观察者对象集合的增、删和通知方法。

       2、ConcreteSubject:具体主题(具体被观察者),将所有观察者放到集合里,再具体主题的内部状态发生变化时,给所有注册过的观察者发送通知。

       3、Observer:抽象观察者,是观察者的抽象类,它定义了一个更新方法,使得再得到被观察者通知时,即时更新自己。

       4、ConcrereObserver:具体观察者,实现抽象观察者的更新方法,更新自己。

    三、观察者模式简单实现

    1、故事情景:企业有一个人源库系统管理所有人员基本信息,还有一个是财务系统和钉钉,财务和钉钉都紧密和人员信息紧密挂钩,假设人源库是被观察者,财务和钉钉是观察者,当人员信息被修改时需要即时通知财务和钉钉更新。

    2、观察者模式UML类图:

    3、让我们来看看代码如何实现的

    抽象观察者(Observer

      里面定义了一个更新的抽象方法

    1 public interface IObserverService {
    2     void update(PeopleEntity peopleEntity);
    3}

    具体观察者(ConcrereObserver

      不同观察者实现抽象方法

     1 /**
     2  *@author : lsy
     3  *@description: 钉钉具体观察者 
     5
    */ 6 @Service 7 public class DingDingObserverImpl implements IObserverService{ 8 @Override 9 public void update(PeopleEntity peopleEntity) { 10 System.out.println("钉钉:"+peopleEntity.toString()); 11 } 12 }
     1 /**
     2  *@author : lsy
     3  *@description: 财务具体观察者
    5 */ 6 @Service 7 public class FinanceObserverImpl implements IObserverService{ 8 @Override 9 public void update(PeopleEntity peopleEntity) { 10 System.out.println("财务系统:"+peopleEntity.toString()); 11 } 12 }

    抽象被观察者(Subject

      定义了新增、移除、通知观察者的抽象方法

     1 /**
     2  *@author : lsy
     3  *@description: 抽象被观察者
     4 */
     5 public interface ISubjectService {
     6     //增加观察者
     7     void attach(IObserverService observerService);
     8 
     9     //移除观察者
    10     void detach(IObserverService observerService);
    11 
    12     //通知观察者
    13     void notice(PeopleEntity peopleEntity);
    14 }

    具体被观察者(ConcreteSubject

      创建一个用于存放观察者List集合,并实现抽象方法

     1 /**
     2  *@author : lsy
     3  *@description: 人源库具体被观察者 5 */
     6 @Service
     7 public class PeopleBasicSubjectImpl implements ISubjectService{
     8     private List<IObserverService> observerServiceList = new ArrayList<>();
     9 
    10     /**
    11      * 增加观察者
    12      * @param observerService
    13      */
    14     @Override
    15     public void attach(IObserverService observerService) {
    16         observerServiceList.add(observerService);
    17     }
    18 
    19     /**
    20      * 移除观察者
    21      * @param observerService
    22      */
    23     @Override
    24     public void detach(IObserverService observerService) {
    25         observerServiceList.remove(observerService);
    26     }
    27 
    28     /**
    29      * 通知观察者
    30      */
    31     @Override
    32     public void notice(PeopleEntity peopleEntity) {
    33         System.out.println("人源库新增:"+peopleEntity.toString());
    34         observerServiceList.forEach(observer -> observer.update(peopleEntity));
    35     }
    36 }

    启动类:

     1 /**
     2  *@author : lsy
     3  *@description: 启动类 5 */
     6 @SpringBootApplication
     7 public class StartClass {
     8     public static void main(String[] args) {
     9         PeopleEntity peopleEntity = new PeopleEntity(1, "测试", "后端", "小菜鸟");
    10         //创建两个观察者
    11         IObserverService dingObserver = new DingDingObserverImpl();
    12         IObserverService financeObserver = new FinanceObserverImpl();
    13         //被观察者具体实现类
    14         ISubjectService peopleBasicSubject = new PeopleBasicSubjectImpl();
    15         //添加观察者
    16         peopleBasicSubject.attach(dingObserver);
    17         peopleBasicSubject.attach(financeObserver);
    18         //通知观察者
    19         peopleBasicSubject.notice(peopleEntity);
    20 
    21     }
    22 }

     控制台输出:

    总结 

    使用观察者模式的场景:
      关联行为场景,需要注意的是,关联行为是可拆分的,而不是“组合”关系。
      事件多级触发场景。
      跨系统的消息交换场景,如消息队列、事件总线的处理机制。
    优点:
      解除耦合,让耦合的双方都依赖于抽象,从而使得各自的变换都不会影响另一边的变换。

    缺点:
      在应用观察者模式时需要考虑一下开发效率和运行效率的问题,程序中包括一个被观察者、多个观察者,开发、调试等内容会比较复杂,而且在Java中消息的通知一般是顺序执行,那么一个观察者卡顿,会影响整体的执行效率,在这种情况下,一般会采用异步实现。

  • 相关阅读:
    电子书、API、帮助文档 链接收藏
    .net上传图片我自己的可下载资源
    VS2012+EF5学习MVC4(二)
    VS2012+EF5学习MVC4(三)
    MVC 3.0 的新特性
    最受欢迎的ASP.NET的CMS下载
    简易甘特图 .net javascript
    VS2010+EF Code First 4.1学习MVC3(三)
    winform WebBrowser 文件下载拦截 获取文件本地保存路径
    一次偶遇 IOException
  • 原文地址:https://www.cnblogs.com/dashuaiguo/p/10531754.html
Copyright © 2011-2022 走看看