概念
当一个对象状态发生变化时,自动通知所有依赖于它的对象,并自动更新它们
应用场景
通常用于自动发布通知的场景,使用观察者模式发布通知后会自动通知所有的需要通知的用户
同时实现将“发布通知”的代码与“通知用户”的代码解耦
统一接口实现多对多通知关系,每种主题可以有多种观察者,每种观察者可以有独立的反应
基本结构

1)主题接口(Subject):定义增加、移除、通知观察者的接口,同时维护观察者列表
2)具体主题(ConcreteSubject):实现主题接口,并在自己的状态发生变化时,通知所有注册的观察者
3)观察者接口(Observer):定义响应通知接口
4)具体观察者(ConcreteObserver):实现观察者接口,接收到通知后,根据需要做出具体处理
代码实现
以“用户发布内容通知粉丝”为例
被观察者接口
声明管理观察者和发布通知的方法
public interface User {
void addFollower(Follower follower);
void removeFollower(Follower follower);
void notifyFollowers(String postContent);
}
观察者接口
声明接收通知的方法
public interface Follower {
void update(String userName, String postContent);
}
具体观察者
维护被观察者
实现通知方法
public class ConcreteFollower implements Follower {
private String name;
public ConcreteFollower(String name) {
this.name = name;
}
@Override
public void update(String userName, String postContent) {
System.out.println(name + " 收到通知:@" + userName + " 发了一条新动态:" + postContent);
}
}
具体被观察者
除实现接口外,编写发布内容的业务代码后,需要调用通知观察者的方法
public class ConcreteUser implements User {
private String userName;
private List<Follower> followers;
public ConcreteUser(String userName) {
this.userName = userName;
this.followers = new ArrayList<>();
}
@Override
public void addFollower(Follower follower) {
followers.add(follower);
}
@Override
public void removeFollower(Follower follower) {
followers.remove(follower);
}
@Override
public void notifyFollowers(String postContent) {
for (Follower f : followers) {
f.update(userName, postContent);
}
}
public void post(String content) {
System.out.println(userName + " 发布动态:" + content);
notifyFollowers(content);
}
}
客户端调用
public class Client {
public static void main(String[] args) {
ConcreteUser star = new ConcreteUser("鱼皮");
Follower f1 = new ConcreteFollower("张三");
Follower f2 = new ConcreteFollower("李四");
Follower f3 = new ConcreteFollower("王五");
star.addFollower(f1);
star.addFollower(f2);
star.addFollower(f3);
star.post("今天阳光真好,适合写代码!");
}
}
优缺点
优点
1)解耦观察者和被观察者:观察者模式让观察者和被观察者之间的依赖关系变得松散。被观察者(主题)不需要知道观察者的具体实现,只需要通知它们状态变化,这样修改一个观察者或添加新观察者时,不会影响到其他部分
2)多对多关系:每种主题可以有多中观察者,每种观察者可以有独立的反应
缺点
1)只能单向通知
