【设计模式】观察者模式

什么是观察者模式?

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

观察者模式的角色:

Subject:抽象主题(被观察者),每一个主题可以有多个观察者,并将所有观察者对象的引用保存在一个集合里,被观察者提供一个接口,可以增加和删除观察者角色

ConcreteSubject:具体主题,将有关状态存入具体观察者对象,在主题发生改变时,给所有的观察者发出通知

Observer:抽象观察者,为所有的具体观察者定义一个更新接口,该接口的作用是在收到主题的通知时能够及时的更新自己

ConcreteObserver:具体观察者,实现抽象观察者角色定义的更新接口,以便使本身的状态与主题状态相协调。如果需要,具体观察者角色可以保存一个指向具体主题角色的引用。

参考来自设计模式(五)观察者模式,作者:刘望舒

观察者模式的使用场景:

观察者模式是一种对象行为型模式,它通常用于以下场景:

  • 消息服务器系统。
  • 社交媒体平台。
  • 邮件系统。
  • 图形界面应用程序。
  • 游戏。
  • 实现团队协作,提高工作效率。
  • 观察者模式可以在不同对象之间创建有效关系,从而更有效地开发高质量软件。

具体实现:

假设有这么一个场景:我是B站up主,有很多粉丝关注我,我发视频了,他们就会点赞我,我发癫了(说些不好的话)他们就会取关我。

在这种场景下,就很使用观察者模式,粉丝们关注我,根据我的状态而动态地做出反应。

观察者的接口

java 复制代码
public interface MyObserver {
    void execute(String upName);
}

观察者对象

java 复制代码
public class fans implements MyObserver {

    private String name;

    public fans(String name){
        this.name = name;
    }
    // 根据msg动态地执行方法
    @Override
    public void execute(String msg) {
        if("更新了".equals(msg)){
            System.out.println(this.name+"点赞了你");
        }
        if("发癫了".equals(msg)){
            System.out.println(this.name+"举报了你");
        }
    }
}

被观察者接口

java 复制代码
public interface SupObject {

    // 将粉丝增加在通知列表
    void add(MyObserver myObserver);

    // 将粉丝删除出通知列表
    void delete(MyObserver myObserver);

    // 通知
    void notify(String upName);
}

被观察者对象

java 复制代码
public class up implements SupObject{

    List<MyObserver> notifyList = new ArrayList<>();

    @Override
    public void add(MyObserver myObserver) {
        notifyList.add(myObserver);
    }

    @Override
    public void delete(MyObserver myObserver) {
        notifyList.remove(myObserver);
    }

    @Override
    public void notify(String msg) {

        notifyList.forEach(t-> t.execute(msg));
    }
}

执行器

java 复制代码
public class client {
    public static void main(String[] args) {

        fans fans1 = new fans("小约翰可汗");
        fans fans2 = new fans("CSGO玩机器");
        fans fans3 = new fans("徐云流浪中国");

        up up = new up();
        up.add(fans1);
        up.add(fans2);
        up.add(fans3);

        up.notify("更新了");
    }
}

效果:

观察者模式的优缺点:

优点

解除耦合,让耦合的双方都依赖于抽象,从而使得各自的变换都不会影响另一边的变换。

缺点

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

观察者模式和发布订阅模式的不同:

通过上面的代码,可能回产生这样的疑问?

这不是"被观察者"主动发送消息给"观察者"的吗?这么叫做观察者模式呢?主被动关系是不是搞反了?

其实观察者模式也叫做发布订阅模式。

比如《heah in first》中,就曾这么写

Publishers + Subscribers = Observer Pattern

但是!他们还是有差别的

在发布订阅模式里,发布者,并不会直接通知订阅者,换句话说,发布者和订阅者,彼此互不相识。

但在观察者模式中,观察者与被观察者是直接通信的。

这就是他们的差别:

观察者模式主打一个松耦合 ,但是他们还是耦合的。

但是发布订阅模式,完完全全的松开了!

相关推荐
海特伟业1 小时前
隧道调频广播覆盖-隧道调频广播无线覆盖系统建设要点、难点分析与解决应对
运维·设计模式
sg_knight1 小时前
设计模式实战:享元模式(Flyweight)
python·设计模式·享元模式·flyweight
Swift社区4 小时前
AI 时代,ArkUI 的设计模式会改变吗?
人工智能·设计模式
数据中穿行4 小时前
访问者设计模式全方位深度解析
设计模式
宁雨桥5 小时前
前端设计模式面试题大全
前端·设计模式
数据中穿行6 小时前
迭代器设计模式全方位深度解析
设计模式
数据中穿行6 小时前
观察者设计模式全方位深度解析
设计模式
程序员Terry6 小时前
别老写重复代码了!模版方法模式一次讲透
java·设计模式
数据中穿行6 小时前
建造者模式全方位深度解析
设计模式
数据中穿行7 小时前
组合设计模式全方位深度解析
设计模式