Java設計模式之觀察者模式(Observer模式)
一、觀察者模式是什么?
當對象間存在一對多關(guān)系時,則使用觀察者模式(Observer Pattern)。當一個對象被修改時,則會自動通知依賴它的對象。觀察者模式屬于行為型模式。
人話: 就像微信公眾號推送消息,訂閱的人能收到,沒訂閱的收不到,還可以取消/添加訂閱
二、模式分析
2.1 四個角色
- 抽象主題(抽象被觀察者角色):也就是一個抽象主題,它把所有對觀察者對象的引用保存在一個集合中,每個主題都可以有任意數(shù)量的觀察者。抽象主題提供一個接口,可以增加和刪除觀察者角色。一般用一個抽象類和接口來實現(xiàn)。
- 抽象觀察者角色:為所有的具體觀察者定義一個接口,在得到主題通知時更新自己。
- 具體主題(具體被觀察者角色):也就是一個具體的主題,在集體主題的內(nèi)部狀態(tài)改變時,所有登記過的觀察者發(fā)出通知。
- 具體觀察者角色:實現(xiàn)抽象觀察者角色所需要的更新接口,一邊使本身的狀態(tài)與制圖的狀態(tài)相協(xié)調(diào)。
2.2 案例
- 微信公眾號
1.抽象主題
public interface Subject {
/**
* 注冊觀察者
*/
void registerObserver(observer observer);
/**
* 移除觀察者
*/
void removeObserver(observer observer);
/**
* 通知觀察者
*/
void notifyObservers();
}
2.抽象觀察者角色
public interface observer {
/**
* 更新
*/
void update(String message);
}
3.具體主題
用Vector是線程同步的,比較安全,也可以使用ArrayList,是線程異步的,但不安全。
public class WechatServer implements Subject{
//注意到這個List集合的泛型參數(shù)為Observer接口,設計原則:面向接口編程而不是面向?qū)崿F(xiàn)編程
private Vector<observer> list;
private String message;
public WechatServer() {
list = new Vector<observer>();
}
@Override
public void registerObserver(observer observer) {
list.add(observer);
}
@Override
public void removeObserver(observer observer) {
if(!list.isEmpty())
list.remove(observer);
}
@Override
public void notifyObservers() {
for(int i = 0; i < list.size(); i++) {
observer oserver = list.get(i);
oserver.update(message);
}
}
public void setInfomation(String s) {
this.message = s;
System.out.println("微信服務更新消息: " + s);
//消息更新,通知所有觀察者
notifyObservers();
}
}
4.具體觀察者角色
public class User implements observer {
private String name;
private String message;
public User(String name) {
this.name = name;
}
@Override
public void update(String message) {
this.message = message;
read();
}
public void read() {
System.out.println(name + " 收到推送消息: " + message);
}
}
5.測試類
public class Test {
public static void main(String[] args) {
//主題
WechatServer server = new WechatServer();
//觀察者
observer userZhang = new User("ZhangSan");
observer userLi = new User("LiSi");
observer userWang = new User("WangWu");
server.registerObserver(userZhang);
server.setInfomation("C是世界上最好用的語言!");
System.out.println("====================================");
server.registerObserver(userLi);
server.registerObserver(userWang);
server.setInfomation("JAVA是世界上最好用的語言!");
}
}
6.結(jié)果

三、觀察者模式的優(yōu)缺點
優(yōu)點
解除耦合,讓耦合的雙方都依賴于抽象,從而使得各自的變換都不會影響另一邊的變換。
缺點
在應用觀察者模式時需要考慮一下開發(fā)效率和運行效率的問題,程序中包括一個被觀察者、多個觀察者,開發(fā)、調(diào)試等內(nèi)容會比較復雜,而且在Java中消息的通知一般是順序執(zhí)行,那么一個觀察者卡頓,會影響整體的執(zhí)行效率,在這種情況下,一般會采用異步實現(xiàn)。
四、總結(jié)
當一個對象的改變需要同時改變其它對象,并且它不知道具體有多少對象有待改變的時候,應該考慮使用觀察者模式。 而使用觀察者模式的動機在于:將一個系統(tǒng)分割成一系列相互協(xié)作的類有一個很不好的副作用,就是需要維護相關(guān)對象間的一致性,我們不希望為了維持一致性而使各類緊密耦合,這樣會給維護、擴展和重用都帶來不便,而觀察者模式所做的工作就是在解除耦合。
到此這篇關(guān)于Java設計模式之觀察者模式(Observer模式)的文章就介紹到這了,更多相關(guān)Java觀察者模式內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Mybatis mapper接口動態(tài)代理開發(fā)步驟解析
這篇文章主要介紹了Mybatis mapper接口動態(tài)代理開發(fā)步驟解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-07-07
Java靜態(tài)static與實例instance方法示例
這篇文章主要為大家介紹了Java靜態(tài)static與實例instance方法示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-08-08
Spring FreeMarker整合Struts2過程詳解
這篇文章主要介紹了Spring FreeMarker整合Struts2過程詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-10-10
Java面向?qū)ο髮崿F(xiàn)汽車租賃系統(tǒng)
這篇文章主要為大家詳細介紹了Java面向?qū)ο髮崿F(xiàn)汽車租賃系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-02-02
SpringBoot2如何集成Elasticsearch6.x(TransportClient方式)
這篇文章主要介紹了SpringBoot2如何集成Elasticsearch6.x(TransportClient方式)問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-05-05

