观察者模式
一、介绍
观察者模式是指定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并自动更新,也叫做发布订阅模式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();
}
}