大话设计模式——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();

    }
}
总结
  • 优点:

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

    • 观察者与被观察者之间如果存在循环依赖,可能会触发彼此之间的循环调用,导致系统崩溃
    • 若一个被观察者对象存在大量观察者对象,如果这些观察者对象都需要通知,会耗费大量时间
相关推荐
向阳2561 分钟前
SpringBoot+vue前后端分离整合sa-token(无cookie登录态 & 详细的登录流程)
java·vue.js·spring boot·后端·sa-token·springboot·登录流程
XiaoLeisj18 分钟前
【MyBatis】深入解析 MyBatis XML 开发:增删改查操作和方法命名规范、@Param 重命名参数、XML 返回自增主键方法
xml·java·数据库·spring boot·sql·intellij-idea·mybatis
风象南19 分钟前
SpringBoot实现数据库读写分离的3种方案
java·spring boot·后端
振鹏Dong25 分钟前
策略模式——本质是通过Context类来作为中心控制单元,对不同的策略进行调度分配。
java·策略模式
ChinaRainbowSea34 分钟前
3. RabbitMQ 的(Hello World) 和 RabbitMQ 的(Work Queues)工作队列
java·分布式·后端·rabbitmq·ruby·java-rabbitmq
雾月5535 分钟前
LeetCode 914 卡牌分组
java·开发语言·算法·leetcode·职场和发展
melck1 小时前
liunx日志查询常用命令总结
java·服务器·网络
守护者1701 小时前
JAVA学习-练习试用Java实现“实现一个Hadoop程序,使用Hive进行复杂查询和数据筛查”
java·学习
程序员 小柴1 小时前
docker的与使用
java·docker·eureka
ゞ 正在缓冲99%…1 小时前
leetcode76.最小覆盖子串
java·算法·leetcode·字符串·双指针·滑动窗口