版權聲明:轉載必須註明本文轉自曉_晨的博客:http://blog.csdn.net/niunai112
目錄
導航
設計模式之六大設計原則
設計模式(一)單例模式
設計模式(二)工廠模式
設計模式(三)策略模式
設計模式(四)適配器模式
設計模式(五)享元模式
設計模式(六)建造者模式
設計模式(七)原型模式
設計模式(八)橋接模式
設計模式(九)外觀模式
設計模式(十)組合模式
設計模式(十一)裝飾器模式
設計模式(十二)代理模式
設計模式(十三)迭代器模式
設計模式(十四)觀察者模式
設計模式(十五)中介者模式
設計模式(十六)命令模式
設計模式(十七)狀態模式
設計模式(十八)訪問者模式
設計模式(十九)責任鏈模式
設計模式(二十)解釋器模式
設計模式(二十一)備忘錄模式
設計模式(二十二)模板模式
設計模式總結篇(爲什麼要學習設計模式,學習設計模式的好處)
前言
觀察者模式:定義對象間的一種一對多的依賴關係,當一個對象的狀態發生改變時, 所有依賴於它的對象都得到通知並被自動更新。
其實用通俗的話講就是訂閱,發佈這樣的流程。
例子
我們經常會去銀行辦理業務,然後當人多的時候,我們就需要拿號來等待銀行叫號。當銀行叫到你的時候,才輪到你辦理業務。萬惡的某行,居然有Vip插隊業務,太噁心了,這個例子中,不包含這噁心的插隊邏輯。
所以LZ需要建4個類,其中2個是觀察者接口,和被觀察者接口,另外2個是實現類,一個銀行呼叫中心和取了號的客戶。
UML類圖
/***
*
*@Author ChenjunWang
*@Description:被觀察者接口
*@Date: Created in 16:11 2018/4/11
*@Modified By:
*
*/
public interface Subject {
//註冊觀察者
void registerObserver(Observer observer);
//移除觀察者
void removeObserver(Observer observer);
//提醒觀察者
void notifyObserver(String msg);
}
/***
*
*@Author ChenjunWang
*@Description: 觀察者接口
*@Date: Created in 16:10 2018/4/11
*@Modified By:
*
*/
public interface Observer {
void update(String msg);
}
/***
*
*@Author ChenjunWang
*@Description: 銀行叫號中心
*@Date: Created in 17:06 2018/4/11
*@Modified By:
*
*/
public class BankCallCenter implements Subject {
List<Observer> list = new ArrayList<>();
@Override
public void registerObserver(Observer observer) {
list.add(observer);
}
@Override
public void removeObserver(Observer observer) {
list.remove(observer);
}
@Override
public void notifyObserver(String msg) {
for (Observer item : list)
item.update(msg);
}
}
/***
*
*@Author ChenjunWang
*@Description:
*@Date: Created in 17:09 2018/4/11
*@Modified By:
*
*/
public class Client implements Observer {
String callNo;
public Client(String callNo) {
this.callNo = callNo;
}
@Override
public void update(String msg) {
if (msg.equals(this.callNo)){
System.out.println("我是" + callNo + "號客戶,現在到我了!");
} else {
System.out.println("我是" + callNo + "號客戶,現在還沒到我了!");
}
}
}
/***
*
*@Author ChenjunWang
*@Description:測試類
*@Date: Created in 17:12 2018/4/11
*@Modified By:
*
*/
public class Test {
public static void main(String[] args) {
BankCallCenter bankCallCenter = new BankCallCenter();
Client client = new Client("1");
bankCallCenter.registerObserver(client);
Client client2 = new Client("2");
bankCallCenter.registerObserver(client2);
Client client3 = new Client("3");
bankCallCenter.registerObserver(client3);
System.out.println("----------中心叫一號去辦理業務------------");
bankCallCenter.notifyObserver("1");
System.out.println("----------從觀察者列表中移除一號------------");
bankCallCenter.removeObserver(client);
System.out.println("-----------中心叫二號去辦理業務-------------");
bankCallCenter.notifyObserver("2");
System.out.println("------------從觀察者列表中移除二號-----------");
}
}
運行結果如下
--------------------------------------
/***
*
*@Author ChenjunWang
*@Description:測試類
*@Date: Created in 17:12 2018/4/11
*@Modified By:
*
*/
public class Test {
public static void main(String[] args) {
BankCallCenter bankCallCenter = new BankCallCenter();
Client client = new Client("1");
bankCallCenter.registerObserver(client);
Client client2 = new Client("2");
bankCallCenter.registerObserver(client2);
Client client3 = new Client("3");
bankCallCenter.registerObserver(client3);
System.out.println("----------中心叫一號去辦理業務------------");
bankCallCenter.notifyObserver("1");
System.out.println("----------從觀察者列表中移除一號------------");
bankCallCenter.removeObserver(client);
System.out.println("-----------中心叫二號去辦理業務-------------");
bankCallCenter.notifyObserver("2");
System.out.println("------------從觀察者列表中移除二號-----------");
}
}
被觀察者利用notifyObserver羣發消息,LZ在update方法中對接受到的消息進行了處理,若收到有用的消息則進行操作。
觀察者模式適合一個軟件系統要求在某一個對象狀態發生變化的時候,某些其他的對象作出相應的改變。觀察者模式減少對象之間的耦合有利於系統的複用。
總結
優點
(1)Subject和Observer之間是鬆耦合的,分別可以各自獨立改變。
(2)Subject在發送廣播通知的時候,無須指定具體的Observer,Observer可以自己決定是否要訂閱Subject的通知。
(3)符合開閉原則
缺點
(1)如果一個Subject被大量Observer訂閱的話,在廣播通知的時候可能會有效率問題。
(2)使得代碼關係變得複雜。
Git地址
本篇實例Github地址:https://github.com/stackisok/Design-Pattern/tree/master/src/observer
有什麼不懂或者不對的地方,歡迎留言。
喜歡LZ文章的小夥伴們,可以關注一波,也可以留言,LZ會回你們的。
覺得寫得不錯的小夥伴,歡迎轉載,但請附上原文地址,謝謝^_^!