观察者模式
解释
指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。这种模式有时又称作发布-订阅模式、模型-视图模式,它是对象行为型模式。
作用
- 一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。如微信公众号推送消息,关注的人都能收到
- 观察者和被观察者是抽象耦合的
- 立一套触发机制。
示例
模式的结构
观察者模式的主要角色如下。
- 抽象主题(Subject)角色:面向对象思想,封装为一个接口,它提供了一个用于观察者对象增加、删除观察者对象的方法,以及通知所有观察者的抽象方法。
- 具体主题(ConcreteSubject)角色:也叫具体目标类,它实现接口中的通知方法,当具体主题的内部状态发生改变时,通知所有注册过的观察者对象。
- 抽象观察者(Observer)角色:它是一个抽象类或接口,它包含了一个更新自己的抽象方法,当接到具体主题的更改通知时被调用。
- 具体观察者(Concrete Observer)角色:实现抽象观察者中定义的抽象方法,以便在得到目标的更改通知时更新自身的状态。
代码
1、Subject接口
public interface Subject {
/**
* 注册观察者
* @param observer
*/
void attach(Observer observer);
/**
* 移除观察者
* @param observer
*/
void detach(Observer observer);
/**
* 通知所有注册的观察者
*/
void notifyObservers();
}
2、SubjectImpl事项Subject
import java.util.ArrayList;
import java.util.List;
public class SubjectImpl implements Subject {
private List<Observer> wechatList=new ArrayList<>();
@Override
public void attach(Observer observer) {
this.wechatList.add(observer);
System.out.println("新增一个观察者(关注了微信公众号)");
}
@Override
public void detach(Observer observer) {
this.wechatList.remove(observer);
System.out.println("删除了一个观察者(取消了微信公众号)");
}
@Override
public void notifyObservers() {
for (Observer wechat: wechatList
) {
wechat.update("我发布了一篇设计模式");
}
}
}
3、Observer类
public interface Observer {
/* 接收到被观察者改变状态*/
void update(String state);
}
4、ObserverImpl实现Observer
public class ObserverImpl implements Observer {
private String name;
public ObserverImpl(String name) {
this.name = name;
}
@Override
public void update(String state) {
System.out.println(name+"---------》"+state);
}
}
5、测试类
import org.junit.Test;
public class TestGC {
@Test
public void test(){
SubjectImpl subject=new SubjectImpl();
Observer observer=new ObserverImpl("张三");
Observer observer1=new ObserverImpl("李四");
/* 张三、李四关注微信公众号*/
subject.attach(observer);
subject.attach(observer1);
/* 对关注的人进行通知*/
subject.notifyObservers();
}
}
6、运行结果
缺点
1、如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
2、如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。
3、观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。