大话设计模式——15.观察者模式(Observer Pattern)

简介

也称发布订阅模式(Publish/Subscribe),定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新

UML图:
应用场景:
  • 消息通知组件:邮件通知、广播通知、朋友圈、私信等
  • 当一个对象的改变需要同时改变其他对象,且不知道具体有多少对象有待改变时
示例
  1. 观察者:Observer
java 复制代码
public interface Observer {

    /**
     * 更新状态
     */
    void updateState();
}
java 复制代码
public class ConcreteObserver01 implements Observer {


    private String observerName;

    private Subject subject;

    public ConcreteObserver01(String observerName, Subject subject) {
        this.observerName = observerName;
        this.subject = subject;
    }

    @Override
    public void updateState() {
        System.out.println(subject.getAction() + "," + observerName + "进入工作状态");
    }
}
java 复制代码
public class ConcreteObserver02 implements Observer {


    private String observerName;

    private Subject subject;

    public ConcreteObserver02(String observerName, Subject subject) {
        this.observerName = observerName;
        this.subject = subject;
    }

    @Override
    public void updateState() {
        System.out.println(subject.getAction() + "," + observerName + "进入工作状态");
    }
}
  1. 目标/主体:Subject
java 复制代码
public class Subject {

    private List<Observer> observerList = new ArrayList<>();

    private String action;

    public String getAction() {
        return action;
    }

    public void setAction(String action) {
        this.action = action;
    }

    public void addObserver(Observer observer) {
        observerList.add(observer);
    }


    public void delObserver(Observer observer) {
        observerList.remove(observer);
    }

    public void notifyObserver() {
        for (Observer observer : observerList) {
            observer.updateState();
        }
    }

}
java 复制代码
public class BossSubject extends Subject {
}
  1. 运行
java 复制代码
public class Main {

    public static void main(String[] args) {
        Subject bossSubject = new BossSubject();
        Observer concreteObserver01 = new ConcreteObserver01("01员工摸鱼", bossSubject);
        Observer concreteObserver02 = new ConcreteObserver02("02员工摸鱼", bossSubject);
        bossSubject.addObserver(concreteObserver01);
        bossSubject.addObserver(concreteObserver02);

        bossSubject.setAction("老板开始巡视");
        bossSubject.notifyObserver();

    }
}
总结
  • 优点:

    • 观察者与被观察者是抽象耦合的,降低了目标与观察者之间的耦合关系
    • 目标与观察者之间建立了一套触发机制
  • 缺点

    • 观察者与被观察者之间如果存在循环依赖,可能会触发彼此之间的循环调用,导致系统崩溃
    • 若一个被观察者对象存在大量观察者对象,如果这些观察者对象都需要通知,会耗费大量时间
相关推荐
像我这样帅的人丶你还6 小时前
Java 后端详解(四):分页与搜索
java·javascript·后端
她的男孩6 小时前
数据权限为什么不能只靠注解?Forge 的 Mapper 层 SQL 改写源码拆解
java·后端·架构
tntxia7 小时前
Mybatis的日志输入
java
亦暖筑序8 小时前
Java 8老系统Browser Agent实战:三层拦截把AI操作后台变成可审计流程
java·后端·设计模式
用户2986985301411 小时前
Java 实现 Word 文档加密与权限解除
java·后端
Yeats_Liao12 小时前
14:Servlet中的页面跳转-Java Web
java·后端·架构
未秃头的程序猿12 小时前
告别"if-else地狱"!Java 21模式匹配,代码优雅了10倍
java·后端·面试
鹤望兰67512 小时前
字节跳动国际支付-后端开发-三面面经
java
Flittly12 小时前
【AgentScope Java新手村系列】(14)人机交互
java·spring boot·spring
RainCity12 小时前
Java Swing 自定义组件库分享(十二)
java·笔记·后端