大数据知识体系
首页
数据结构与算法
  • JVM
  • Java
  • Scala
  • Python
设计模式
  • MySQL
  • Redis
  • HDFS
  • HBase
  • ClickHouse
  • ElasticSearch
  • Iceberg
  • Hudi
  • Spark
  • Flink
  • Hive
  • Yarn
  • Zookeeper
  • Maven
  • Git
  • 数据仓库
  • 用户画像
  • 指标体系
数据治理
关于
首页
数据结构与算法
  • JVM
  • Java
  • Scala
  • Python
设计模式
  • MySQL
  • Redis
  • HDFS
  • HBase
  • ClickHouse
  • ElasticSearch
  • Iceberg
  • Hudi
  • Spark
  • Flink
  • Hive
  • Yarn
  • Zookeeper
  • Maven
  • Git
  • 数据仓库
  • 用户画像
  • 指标体系
数据治理
关于
  • 设计模式概述
  • 创建型模式

    • 单例模式
    • 简单工厂模式
    • 工厂方法模式
    • 抽象工厂模式
    • 建造者模式
    • 原型模式
  • 结构型模式

    • 适配器模式
    • 装饰器模式
    • 代理模式
    • 外观模式
    • 桥接模式
    • 组合模式
    • 享元模式
  • 行为型模式

    • 策略模式
    • 模板方法模式
    • 观察者模式
      • 一、概述
        • 1.1 解决了什么问题
        • 1.2 解决方案
      • 二、实现方式
        • 2.1 角色
        • 2.2 代码
      • 三、源码中的应用
    • 迭代器模式
    • 责任链模式
    • 命令模式
    • 备忘录模式
    • 状态模式
    • 访问者模式
    • 中介者模式
    • 解释器模式
  • 设计模式
  • 行为型模式
Will
2022-03-29
目录

观察者模式

# 一、概述

观察者(Observer)模式其实是实现一种订阅机制,它定义了对象间一种一对多的依赖关系,使得当某个对象的状态发生改变时,所有依赖它的对象都会得到通知并自动更新。

# 1.1 解决了什么问题

烟草公司对每个零售商每个月可以销售的香烟品牌和数量是限制的,因此很多小规模的零售商经常会出现供不应求的现象,村头的小卖部就是这样,经常会卖断货。但是村里的老烟鬼并不知道小卖部什么时候会补货,于是他们只能每天都往小卖部跑一趟问老板。更气人的是,好不容易有烟了,结果还是六七十块一包的华子,抽不起抽不起,白跑一趟。其实小卖部老板也烦求的很,每天中午睡觉的时候就被这些老烟鬼喊醒。

# 1.2 解决方案

为了保证自己自己不被打扰,于是小卖部老板建了个微信群,把这些老烟鬼拉到群里,有新货之后就在群里通知。其实就是发布订阅机制。

# 二、实现方式

# 2.1 角色

总的来说,观察者模式有两个角色:观察者与被观察者。

  1. Subject:抽象的被观察者,定义了观察者订阅和取消订阅的方法,以及状态发生变更时通知观察者的方法。
  2. ConcreteSubject:具体观察者,实现了 Subject 中的所有方法。
  3. Observer:抽象观察者,定义接受时间通知的接口。
  4. ConcreteObserver:具体观察者,实现了 Observer 中的方法。

# 2.2 代码

观察者接口:

public interface Observer {
    void update(String message);
}
1
2
3

被观察者接口:

public interface Subject {
    void subscribe(String topic, Observer observer);

    void unsubscribe(String topic, Observer observer);

    void notify(String topic);
}
1
2
3
4
5
6
7

具体观察者:

public class Consumer implements Observer {

    private String name;

    public Consumer(String name) {
        this.name = name;
    }

    @Override
    public void update(String message) {
        System.out.println(name + "收到:" + message);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13

具体被观察者:

/**
 * 超市老板,具体的被观察者
 */
public class SupermarketOwner implements Subject {

    Map<String, List<Observer>> listeners = new HashMap<>();

    @Override
    public void subscribe(String topic, Observer observer) {
        List<Observer> observers = listeners.get(topic);
        if (observers == null) {
            observers = new ArrayList<>();
            observers.add(observer);
            listeners.put(topic, observers);
        } else {
            observers.add(observer);
        }
    }

    @Override
    public void unsubscribe(String topic, Observer observer) {
        List<Observer> observers = listeners.get(topic);

        if (observers == null) {
            System.out.println("主题不存在");
        } else {
            observers.remove(observer);
        }
    }

    @Override
    public void notify(String topic) {
        List<Observer> observers = listeners.get(topic);

        if (observers != null) {
            for (Observer observer : observers) {
                observer.update(topic + "到货了");
            }
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

客户端:

public class ObserverTest {
    public static void main(String[] args) {
        Subject subject = new SupermarketOwner();
        subject.subscribe("黑兰州", new Consumer("王老二"));
        subject.subscribe("黑兰州", new Consumer("王老三"));
        subject.subscribe("利群", new Consumer("张老六"));
        subject.subscribe("利群", new Consumer("张老七"));
        subject.subscribe("利群", new Consumer("张老八"));
        subject.subscribe("华子", new Consumer("村长"));

        subject.notify("华子");
        System.out.println("------------");
        subject.notify("利群");
        System.out.println("------------");
        subject.notify("黑兰州");
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
村长收到:华子到货了
------------
张老六收到:利群到货了
张老七收到:利群到货了
张老八收到:利群到货了
------------
王老二收到:黑兰州到货了
王老三收到:黑兰州到货了
1
2
3
4
5
6
7
8

# 三、源码中的应用

  1. java.util.Observer(opens new window)
  2. java.util.EventListener
上次更新: 2023/11/01, 03:11:44

← 模板方法模式 迭代器模式→

Theme by Vdoing | Copyright © 2022-2023 Will 蜀ICP备2022002285号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式