观察者模式(ObserverPattern)是一种行为型模式,它提供了一种定义对象之间一对多关系的方式。
引
顾名思义,观察者模式自然是需要有一些观察者(Observer)去"观察"被观察者(Subject)的行为,同时被观察者的状态(status)随时有可能发生改变,当这种改变发生的时候,被观察者需要去"通知"所有正在"观察自己"的观察者们。
观察者和被观察者之间的这种关系也可以叫做"订阅——发布",所以观察者模式又叫做发布订阅模式。
正文
有一个博客平台(Subject)定期会推送文章,已经订阅过得QQ或者WeChat用户(Observer)。这就构成了一个简单的观察者模式的应用场景。
被观察者:
public abstract class Blog {
//关注列表,维护一对多的关系
private final List<User> users = new ArrayList<>();
//关注
public Blog subscribe(User user) {
users.add(user);
return this;
}
//取关
public void unsubscribe(User user) {
users.remove(user);
}
//有文章更新,通知关注列表里的人
public void notifyUsers() {
users.forEach(User::update);
}
}
public class MyBlog extends Blog {
public void doSomethings() {
//业务代码。。。
//通知关注用户
super.notifyUsers();
}
}
观察者:
public interface User {
//接收被观察者的通知消息
void update();
}
public class QQUser implements User {
private String QQName;
public QQUser(String QQName) {
this.QQName = QQName;
}
@Override
public void update() {
System.out.println("QQ用户"+ QQName +"收到提醒!");
}
}
public class WeChatUser implements User {
private String WeChatName;
public WeChatUser(String weChatName) {
WeChatName = weChatName;
}
@Override
public void update() {
System.out.println("WeChat用户"+ WeChatName +"收到提醒!");
}
}
验证:
public static void main(String[] args) {
MyBlog myBlog = new MyBlog();
myBlog.subscribe(new QQUser("煎饼果子"))
.subscribe(new WeChatUser("aa"))
.subscribe(new QQUser("韭菜盒子"));
myBlog.doSomethings();
}
//QQ用户煎饼果子收到提醒!
//WeChat用户aa收到提醒!
//QQ用户韭菜盒子收到提醒!
类图:
在 JDK 中也提供了对观察者模式的支持,被观察者可以继承父类 java.util.Observable
,观察者可以实现 java.util.Observable
接口。
总
优点:被观察者和观察者是抽象耦合的,该模式建立了一套触发机制。
缺点:如果被观察者有很多直接或间接的观察者时,通知每一个观察者会很花费时间。如果观察者和被观察者有循环依赖调用的时候可能会导致系统崩溃。没有一个机制让观察者直到被观察者是怎么发生变化的,仅仅知道目标发生了变化。
菜鸟本菜,不吝赐教,感激不尽!