观察者模式
一、介绍
观察者模式是指定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并自动更新,也叫做发布订阅模式Publish/Subscribe, 属于行为型模式
二、应用场景
消息通知里面:邮件通知、广播通知、微信朋友圈、微博私信等,就是监听观察事件
当一个对象的改变需要同时改变其它对象,且它不知道具体有多少对象有待改变的时候,考虑使用观察者模式
三、角色
Subject主题:持有多个观察者对象的引用,抽象主题提供了一个接口可以增加和删除观察者对象;有一个观察者数组,并实现增、删及通知操作
Observer抽象观察者:为具体观察者定义一个接口,在得到主题的通知时更新自己
ConcreteSubject具体主题:将有关状态存入具体观察者对象,在具体主题内部状态改变时,给所有登记过的观察者发出通知
ConcreteObserver具体观察者:实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态保持一致
四、优缺点
优点
降低了目标与观察者之间的耦合关系,目标与观察者之间建立了一套触发机制
观察者和被观察者是抽象耦合的
缺点
观察者和观察目标之间有循环依赖的话,会触发它们之间进行循环调用,可能导致系统崩溃
一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间
五、代码
观察者抽象接口--消费者抽象
java
package com.lcy.study.design.observe;
public interface Observe {
/**
* 消费通知
**/
void consumeMessage();
}消息发送者抽象类
java
package com.lcy.study.design.observe;
import java.util.ArrayList;
import java.util.List;
public abstract class Subject {
/**
* 观察者列表
*/
private final List<Observe> observes = new ArrayList<>();
/**
* 添加观察者
* @param observe 观察者对象
**/
public void addObserve(Observe observe){
observes.add(observe);
}
/**
* 删除观察者
* @param observe 观察者对象
**/
public void delObserve(Observe observe){
observes.remove(observe);
}
/**
* 通知消息
**/
public void notifyObserve() {
observes.forEach(Observe :: consumeMessage);
}
}消息具体生产者
java
package com.lcy.study.design.observe;
public class ProductSubject extends Subject {
/**
* 发送消息
**/
public void sendProduct() {
System.out.println("发送消息");
notifyObserve();
}
}具体观察者
java
package com.lcy.study.design.observe;
public class ConsumerObserve implements Observe {
@Override public void consumeMessage() {
System.out.println("消费消息");
}
}调用类
java
package com.lcy.study.design.observe;
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();
}
}