什么是观察者模式
观察者模式(Observer Pattern):定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。
观察者模式又叫做:
-
发布-订阅(Publish/Subscribe)模式
-
模型-视图(Model/View)模式
-
源-监听器(Source/Listener)模式
-
从属者(Dependents)模式
观察者模式是一种对象行为型模式。
策略模式的结构:
◉ Subject:被观察者
◉ ConcreteSubject:具体被观察者
◉ Observer:观察者
◉ ConcreteObserver:具体观察者
例如,微信公众号推送消息,微信用户就是观察者,微信公众号作者就是被观察者,当作者发布一篇文章,关注了公众号的用户就会接收到文章。
如何评价观察者模式
优点:
◉ 降低了目标与观察者之间的耦合关系,两者之间是抽象耦合关系。
◉ 目标与观察者之间建立了一套触发机制。
◉ 观察者模式符合 “开闭原则” 的要求。
缺点:
◉ 如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。
◉ 观察者仅仅知道了被观察者的状态发生改变,并不能知道被观察者是如何发生改变。
◉ 如果观察者非常多的话,需要耗费一定的时间通知所有观察者。
怎么实现观察者模式
一、定义被观察者接口(微信公众号作者)
// 定义被观察者接口
public interface AuthorSubject {
// 发布文章
void postArticle(Article article);
// 添加观察者
void addUserObserver(UserObserver observer);
}
二、定义具体被观察者(具体某个公众号作者)
// 定义具体被观察者
public class AuthorConcreteSubject implements AuthorSubject {
// 作者名称
private String name = "作者";
// 存放观察者
List<UserObserver> observerList = new ArrayList<>();
public AuthorConcreteSubject() {
super();
}
public AuthorConcreteSubject(String name) {
super();
this.name = name;
}
public void postArticle(Article article) {
// 发布文章
System.out.println(name +"发布了一篇文章!");
// 通知关注了我的用户(观察者)
observerList.forEach(observer -> observer.getArticle(article));
}
public void addUserObserver(UserObserver observer) {
observerList.add(observer);
System.out.println("一个微信用户关注了你!");
}
}
三、定义观察者接口(微信用户)
// 定义具体观察者
public interface UserObserver {
// 接收到文章
void getArticle(Article article);
}
四、定义具体观察者接口(关注了具体某个公众号的微信用户)
public class UserConcreteObserver implements UserObserver {
// 用户名称
private String name = "用户";
public UserConcreteObserver() {
super();
}
public UserConcreteObserver(String name) {
super();
this.name = name;
}
public void getArticle(Article article) {
System.out.println(name+"接收到一篇文章!");
}
}
五、模拟客户端调用
public class Client {
public static void main(String[] args) throws Exception {
// 实现具体被观察者类
AuthorSubject subject = new AuthorConcreteSubject("漂风");
// 实现具体观察者类
UserObserver user1 = new UserConcreteObserver("用户1");
UserObserver user2 = new UserConcreteObserver("用户2");
UserObserver user3 = new UserConcreteObserver("用户3");
// 注册观察者
subject.addUserObserver(user1);
subject.addUserObserver(user2);
subject.addUserObserver(user3);
// 被观察者状态发生改变
subject.postArticle(new Article());
// 控制台将会打印出
/*
* 漂风发布了一篇文章
* 用户1接收到一篇文章!
* 用户2接收到一篇文章!
* 用户3接收到一篇文章!
*/
}
}