前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java设计模式-观察者模式(订阅发布模式)

Java设计模式-观察者模式(订阅发布模式)

作者头像
宁在春
发布2022-10-31 15:43:40
9580
发布2022-10-31 15:43:40
举报
文章被收录于专栏:关于Java学习@宁在春

Java设计模式-观察者模式(订阅发布模式) 一起来看 会了就当复习丫,不会来一起来看看吧。 很喜欢一句话:“八小时内谋生活,八小时外谋发展”。 如果你也喜欢,让我们一起坚持吧!! 共勉😁

在这里插入图片描述
在这里插入图片描述

特别喜欢这张图片,有喜欢的云,又有着滚滚红尘 作者:用心笑*😁

一、前言

1)引入:

在现实世界中,许多对象并不是独立存在的,其中一个对象的行为发生改变可能会导致一个或者多个其他对象的行为也发生改变。

例如,股票价格与股民、微信公众号与微信用户、气象局的天气预报与听众等。还有上课铃声响了,该进教室啦。

在软件世界也是这样,例如,Excel 中的数据与折线图、饼状图、柱状图之间的关系;MVC 模式中的模型与视图的关系;事件模型中的事件源与事件处理者。所有这些,如果用观察者模式来实现就非常方便。

2)概述:

观察者(Observer)模式的定义:指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。这种模式有时又称作发布-订阅模式、模型-视图模式,它是对象行为型模式。

3)角色结构:

  1. Subject:抽象主题(抽象被观察者),抽象主题角色把所有观察者对象保存在一个集合里,每个主题都可以有任意数量的观察者,抽象主题提供一个接口,可以增加和删除观察者对象。
  2. ConcreteSubject:具体主题(具体被观察者),该角色将有关状态存入具体观察者对象,在具体主题的内部状态发生改变时,给所有注册过的观察者发送通知。
  3. Observer:抽象观察者,是观察者的抽象类,它定义了一个更新接口,使得在得到主题更改通知时更新自己。
  4. ConcrereObserver:具体观察者,实现抽象观察者定义的更新接口,以便在得到主题更改通知时更新自身的状态。

4)注意事项:

1、避免循环引用。 2、如果顺序执行,某一观察者错误会导致系统卡壳,一般采用异步方式。

二、案例代码

2.1、案例:

【例】微信公众号

在使用微信公众号时,大家都会有这样的体验,当你关注的公众号中有新内容更新的话,它就会推送给关注公众号的微信用户端。我们使用观察者模式来模拟这样的场景,微信用户就是观察者微信公众号是被观察者,有多个的微信用户关注了XXX这个公众号。

类图

在这里插入图片描述
在这里插入图片描述

2.2、实现:

定义抽象观察者类,里面定义一个更新的方法

代码语言:javascript
复制
public interface Observer {
    void update(String message);
}

定义具体观察者类,微信用户是观察者,里面实现了更新的方法

代码语言:javascript
复制
public class WeixinUser implements Observer {
    // 微信用户名
    private String name;

    public WeixinUser(String name) {
        this.name = name;
    }
    @Override
    public void update(String message) {
        System.out.println(name + "-" + message);
    }
}

定义抽象主题类,提供了attach、detach、notify三个方法

代码语言:javascript
复制
public interface Subject {
    //增加订阅者
    public void attach(Observer observer);

    //删除订阅者
    public void detach(Observer observer);
    
    //通知订阅者更新消息
    public void notify(String message);
}

微信公众号是具体主题(具体被观察者),里面存储了订阅该公众号的微信用户,并实现了抽象主题中的方法

代码语言:javascript
复制
public class SubscriptionSubject implements Subject {
    //储存订阅公众号的微信用户
    private List<Observer> weixinUserlist = new ArrayList<Observer>();

    @Override
    public void attach(Observer observer) {
        weixinUserlist.add(observer);
    }

    @Override
    public void detach(Observer observer) {
        weixinUserlist.remove(observer);
    }

    @Override
    public void notify(String message) {
        for (Observer observer : weixinUserlist) {
            observer.update(message);
        }
    }
}

客户端程序

代码语言:javascript
复制
public class Client {
    public static void main(String[] args) {
        SubscriptionSubject mSubscriptionSubject=new SubscriptionSubject();
        //创建微信用户
        WeixinUser user1=new WeixinUser("小明");
        WeixinUser user2=new WeixinUser("小王");
        WeixinUser user3=new WeixinUser("小李");
        //订阅公众号
        mSubscriptionSubject.attach(user1);
        mSubscriptionSubject.attach(user2);
        mSubscriptionSubject.attach(user3);
        //公众号更新发出消息给订阅的微信用户
        mSubscriptionSubject.notify("宁在春的文章更新啦!!!");
        /**
         * 小明-宁在春的文章更新啦!!!
         * 小王-宁在春的文章更新啦!!!
         * 小李-宁在春的文章更新啦!!!
         */
    }
}

微信公众号一发消息,所有订阅的用户都能接收到。

之前写过一篇 SpringBoot整合Redis实现发布/订阅模式 的文章。大家感兴趣可以看一看哈!!!

三、总结

优点:

  1. 降低了目标与观察者之间的耦合关系,两者之间是抽象耦合关系。符合依赖倒置原则。
  2. 目标与观察者之间建立了一套触发机制。

缺点:

1、如果有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。

2、如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。

3、观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。(即没有确认机制)

使用场景:

  1. 对象间存在一对多关系,一个对象的状态发生改变会影响其他对象。
  2. 当一个抽象模型有两个方面,其中一个方面依赖于另一方面时,可将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。
  3. 实现类似广播机制的功能,不需要知道具体收听者,只需分发广播,系统中感兴趣的对象会自动接收该广播。
  4. 多层级嵌套使用,形成一种链式触发机制,使得事件具备跨域(跨越两种观察者类型)通知

四、自言自语

我也不知道文章写出来是有用还是无用,只是想做一个分享。希望大家能够喜欢并且在这里能有收获。

当然不可否认,我也想获得那种别人认可的那种快乐,并且能人我继续维之坚持。

你好啊,要天天开心哦。下篇文章再见。

此系列还在持续更新中… 我一定还会回来的。😁

希望与君共勉,我们:待别日相见时,都已有所成

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-01-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、前言
    • 1)引入:
      • 2)概述:
        • 3)角色结构:
          • 4)注意事项:
          • 二、案例代码
            • 2.1、案例:
              • 2.2、实现:
              • 三、总结
                • 优点:
                  • 缺点:
                    • 使用场景:
                    • 四、自言自语
                    相关产品与服务
                    云数据库 Redis
                    腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档