一、初識
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 來實觀察者模式。但是被觀察者是一個類而不是接口,限制了它的複用能力。(因爲類只能單繼承,而接口則可以實現多個接口)