Skip to content

观察者模式

一、介绍

观察者模式是指定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并自动更新,也叫做发布订阅模式Publish/Subscribe,属于行为型模式

二、应用场景

  • 消息通知里面:邮件通知、广播通知、微信朋友圈、微博私信等,就是监听观察事件
  • 当一个对象的改变需要同时改变其它对象,且它不知道具体有多少对象有待改变的时候,考虑使用观察者模式

三、角色

  • Subject主题:持有多个观察者对象的引用,抽象主题提供了一个接口可以增加和删除观察者对象;有一个观察者数组,并实现增、删及通知操作

  • Observer抽象观察者:为具体观察者定义一个接口,在得到主题的通知时更新自己

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

  • ConcreteObserver具体观察者:实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态保持一致

四、优缺点

  • 优点
    • 降低了目标与观察者之间的耦合关系,目标与观察者之间建立了一套触发机制
    • 观察者和被观察者是抽象耦合的
  • 缺点
    • 观察者和观察目标之间有循环依赖的话,会触发它们之间进行循环调用,可能导致系统崩溃
    • 一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间

五、代码

观察者抽象接口--消费者抽象

package com.lcy.study.design.observe;

/**
 * @Description 消息观察者抽象接口
 * @Author lcy
 * @Date 2021/7/27 10:35
 */
public interface Observe {

    /**
     * 消费通知
     * @author lcy
     * @date 2021/7/27 10:37
     **/
    void consumeMessage();

}

消息发送者抽象类

package com.lcy.study.design.observe;

import java.util.ArrayList;
import java.util.List;

/**
 * @Description 消息发送者抽象接口
 * @Author lcy
 * @Date 2021/7/27 10:33
 */
public abstract class Subject {

    /**
     * 观察者列表
     */
    private final List<Observe> observes = new ArrayList<>();

    /**
     * 添加观察者
     * @param observe 观察者对象
     * @author lcy
     * @date 2021/7/27 10:34
     **/
    public void addObserve(Observe observe){
        observes.add(observe);
    }

    /**
     * 删除观察者
     * @param observe 观察者对象
     * @author lcy
     * @date 2021/7/27 14:14
     **/
    public void delObserve(Observe observe){
        observes.remove(observe);
    }

    /**
     * 通知消息
     * @author lcy
     * @date 2021/7/27 10:33
     **/
    public void notifyObserve(){
        observes.forEach(Observe :: consumeMessage);
    }

}

消息具体生产者

package com.lcy.study.design.observe;

/**
 * @Description 消息生产者
 * @Author lcy
 * @Date 2021/7/27 10:33
 */
public class ProductSubject extends Subject {

    /**
     * 发送消息
     * @author lcy
     * @date 2021/7/27 14:10
     **/
    public void sendProduct(){
        System.out.println("发送消息");

        notifyObserve();
    }

}

具体观察者

package com.lcy.study.design.observe;

/**
 * @Description 具体观察者--消费消息
 * @Author lcy
 * @Date 2021/7/27 10:35
 */
public class ConsumerObserve implements Observe {

    @Override public void consumeMessage(){
        System.out.println("消费消息");
    }
}

调用类

package com.lcy.study.design.observe;

/**
 * @Description 观察者模式调用类
 * @Author lcy
 * @Date 2021/7/27 14:16
 */
public class ObserveMain {

    public static void main(String[] args){
        ProductSubject productSubject = new ProductSubject();

        Observe observe1 = new ConsumerObserve();
        Observe observe2 = new ConsumerObserve();
        productSubject.addObserve(observe1);
        productSubject.addObserve(observe2);

        productSubject.sendProduct();

    }
}