一、初识
1.定义
- 在对象之间定义了一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象会收到通知并自动更新。
2.参与角色
-
被观察者(Subject):当需要被观察的状态发生变化时,需要通知队列中所有观察者对象。Subject 需要维持(添加,删除,通知)一个观察者对象的队列列表。
-
观察者(Observer):接口或抽象类。当 Subject 的状态发生变化时,Observer 对象将通过一个 callback 函数得到通知。
3.应用场景
-
聊天室程序,服务器转发信息给所有客户端。
-
网络游戏,服务器将客户端状态进行分发。
-
邮件订阅等。
4.UML
二、使用示例
1.应用场景
- 有一个微信公众号服务,不定时发布一些消息,关注公众号就可以收到推送消息,取消关注就收不到推送消息。
2.具体实现
- 观察者接口
package designpatterns.observer;
/**
* 观察者接口
* */
public interface Observer {
/**
* 定义更新方法
* 收到通知的时候,进行更新
* */
public abstract void update(String info);
}
- 被观察者接口
package designpatterns.observer;
/**
* 被观察者接口
* */
public interface Observerable {
/**
* 定义维持观察者的接口 :添加,删除,通知所有
* */
void add(Observer observer);
void remove(Observer observer);
void notifyAllObserver(String info);
}
- 观察者实现类
package designpatterns.observer;
public class Client implements Observer {
private String name;
public Client(String name) {
this.name = name;
}
@Override
public void update(String info) {
System.out.println(name + " 接收到信息:" + info);
}
}
- 被观察者实现类
package designpatterns.observer;
import java.util.ArrayList;
import java.util.List;
public class Server implements Observerable {
// 定义持有观察者的队列
private List<Observer> list;
public Server() {
list = new ArrayList<>();
}
@Override
public void add(Observer observer) {
list.add(observer);
}
@Override
public void remove(Observer observer) {
if (!list.isEmpty()) {
list.remove(observer);
}
}
@Override
public void notifyAllObserver(String info) {
for (Observer o : list) {
o.update(info);
}
}
public void serverAction(String info) {
System.out.println("服务器更新信息啦");
notifyAllObserver(info);
}
}
- 生产环境
package designpatterns.observer;
public class Demo {
public static void main(String[] args) {
Server server = new Server();
Client c1 = new Client("xsj");
Client c2 = new Client("wr");
Client c3 = new Client("baby");
server.add(c1);
server.add(c2);
server.serverAction("生个娃吧");
System.out.println("******熊孩子分割线******");
// 添加一个用户
server.add(c3);
server.serverAction("一家人整整齐齐");
}
}
- 运行结果
服务器更新信息啦
xsj 接收到信息:生个娃吧
wr 接收到信息:生个娃吧
******熊孩子分割线******
服务器更新信息啦
xsj 接收到信息:一家人整整齐齐
wr 接收到信息:一家人整整齐齐
baby 接收到信息:一家人整整齐齐
注意,在 JDK 中已经提供了 java.util.Observable 和 java.util.Observer 来实观察者模式。但是被观察者是一个类而不是接口,限制了它的复用能力。(因为类只能单继承,而接口则可以实现多个接口)