什么是观察者设计模式
观察者模式主要应用在对象存在一对多关系的情况下,那么如果一个对象,依赖于另一个对象,那个被依赖的对象一旦被修改,依赖于他的那个对象也会被观察者所告知。
观察者模式又被称作为发布-订阅模式,另一种解释:多个观察者同时监听某个主题,当这个主题被修改时,会告知所有的观察者,这样观察者就能主动地更新自己(我觉得用发布订阅更好理解):
-
观察者模式中的几个重要角色:
- 抽象主题:提供一个观察者对象的集合,以及增加删除观察者对象的方法,还有通知所有观察者的抽象方法。
- 具体主题:继承上面的抽象主题,实现通知方法,当具体主题的状态发生了变化时,就会通知所有观察者,这个类根据具体项目来定。
- 抽象观察者:一个抽象类或者接口,有一个接到具体主题通知后的更新自己的方法
- 具体观察者:实现抽象观察者中的更新自己的方法。
-
需要解决的问题
- 如何获取到对象的状态发生改变
- 怎么设计这个观察者,去通知其他对象
观察者设计模式的优缺点
-
优点:
- 在观察者和被观察者(即具体主题)之间建立了一种抽象的耦合(观察者和被观察者可以独立修改,互不影响)
- 自己建立了一种触发机制
-
缺点:
- 观察者过多时,发布通知会消耗大量时间
简单的代码实现
- 抽象观察者
/**
* 抽象观察者中定义更新自己的方法
*/
public interface Observer {
void update(String message);
}
- 具体观察者
这里以微博为例,所有的微博用户就是观察者
public class WeiboUser implements Observer{
private String name;
public WeiboUser(String name) {
this.name = name;
}
@Override
public void update(String message) {
System.out.println(name+"关注的"+message+"更新了");
}
}
- 抽象主题
public interface Subject {
/**
* 增加观察者
*/
void addObserver(Observer observer);
/**
* 删除观察者
*/
void deleteObserver(Observer observer);
/**
* 通知所有观察者的方案
*/
void notify(String message);
}
- 具体主题
既然微博用户是观察者,那么这里的具体主题,就是他们关注的某某明星
public class WeiboSubject implements Subject{
/**
* 关注这个明星的所有微博用户
*/
List<Observer> users = new ArrayList<>();
@Override
public void addObserver(Observer observer) {
users.add(observer);
}
@Override
public void deleteObserver(Observer observer) {
users.remove(observer);
}
@Override
public void notify(String message) {
for (Observer user : users) {
//将消息传给每一个观察者
user.update(message);
}
}
}
- 测试
public class TestObserver {
public static void main(String[] args) {
//微博明星账号
WeiboSubject weiboSubject = new WeiboSubject();
//微博用户账号
WeiboUser weiboUser = new WeiboUser("ikun1");
WeiboUser weiboUser1 = new WeiboUser("ikun2");
WeiboUser weiboUser2 = new WeiboUser("ikun3");
//用户订阅了明星
weiboSubject.addObserver(weiboUser);
weiboSubject.addObserver(weiboUser1);
weiboSubject.addObserver(weiboUser2);
//明星更新,用户接到通知
weiboSubject.notify("蔡徐坤");
}
}
测试结果