觀察者模式是這樣定義的:在對象之間存在一對多的依賴關係,當主對象的狀態發生改變的時候,依賴它的全部從對象都能接收到改變的信息並作出相應的處理。好比老師和學生,微信公衆號和訂閱的用戶,消息隊列的生產者和消費者。觀察者模式的實質就是發佈訂閱模式,發佈者發佈消息,訂閱者獲取消息,訂閱了就能收到消息,沒訂閱就收不到消息。bash
觀察者模式有四個角色:
一、抽象被觀察者:也就是一個抽象的主題,它將全部觀察者放到一個集合(隊列)中,這個主題定義了添加觀察者、一處觀察者,以及通知觀察者等方法。
二、抽象觀察者:爲具體的觀察者定義了一個接口
三、具體被觀察者:對應一個具體的主題,在自身主題的內部發生變化時,通知集合中的全部觀察者
四、具體觀察者:依賴具體的被觀察者,對應它的主題,實現接收通知的接口。微信
你們都熟悉這麼一個場景,咱們訂閱了不少了微信公衆號,這些微信公衆號後臺都有管理員在運營,當他們在後臺發佈了一篇推文,咱們這些訂閱了的用戶均可以收到這篇推文,微信公衆號就是被觀察者,訂閱的用戶就是觀察者。ide
/**
* 抽象被觀察者接口,定義添加,移除和通知觀察者的接口
*/
public interface Observable {
public void registerObserver(Observer observer);
public void removeObserver(Observer observer);
public void notifyObserver();
}
複製代碼
/**
* 抽象觀察者接口,定義接收通知方法
*/
public interface Observer {
public void updateMessage(String message);
}
複製代碼
/**
* 被觀察者,微信公衆號/服務號/訂閱號
* 實現了Observable,實現添加訂閱者,刪除訂閱者,通知訂閱者的基本功能
*/
public class WechatServer implements Observable{
private List<Observer> observers;
private String message;
public WechatServer() {
observers = new ArrayList<>();
}
@Override
public void registerObserver(Observer observer) {
if (observers == null) {
observers = new ArrayList<>();
}
observers.add(observer);
}
@Override
public void removeObserver(Observer observer) {
if (observers == null || observers.isEmpty()) {
return;
}
observers.remove(observer);
}
@Override
public void notifyObserver() {
if (observers == null) {
return;
}
for (Observer observer : observers) {
observer.updateMessage(message);
}
}
public void publicMessage(String message) {
if (StringUtils.isBlank(message)) {
throw new IllegalArgumentException("不能發佈空消息");
}
this.message = message;
System.out.println("微信公衆號管理員發佈信息:"+message);
//通知全部訂閱者
notifyObserver();
}
}
複製代碼
public class WechatUser implements Observer{
private String name;
private String message;
public WechatUser(String name) {
this.name = name;
}
@Override
public void updateMessage(String message) {
this.message = message;
System.out.println(name+"收到推送消息:"+message);
}
}
複製代碼
public static void main(String [] args) {
//定義微信公衆號
WechatServer server = new WechatServer();
//定義三個訂閱的用戶
WechatUser user1 = new WechatUser("喬峯");
WechatUser user2 = new WechatUser("令狐沖");
WechatUser user3 = new WechatUser("楊過");
//三人訂閱了公衆號
server.registerObserver(user1);
server.registerObserver(user2);
server.registerObserver(user3);
//微信公衆號發佈消息
server.publicMessage("JAVA是最流行的語言!!");
//喬峯取消了訂閱
server.removeObserver(user1);
//微信公衆號再次發佈消息(取消訂閱的用戶鄭光宇就收不到消息了)
server.publicMessage("JAVA是最好用的語言!!");
}
複製代碼
運行結果:測試