標籤:其他 分享圖片 author arraylist date pat class 點擊 行操作
項目連結:https://github.com/stackisok/Design-Pattern/tree/master/src/observer
項目背景:去銀行辦理業務,當人多的時候,我們要按順序取號等待。直到銀行叫到自己的號時,才輪到自己去進行辦理。
觀察者模式
觀察者模式(有時又被稱為模型-視圖(View)模式、源-收聽者(Listener)模式或從屬者模式)是軟體設計模式的一種。在此種模式中,一個目標物件管理所有相依於它的觀察者物件,並且在它本身的狀態改變時主動發出通知。這通常透過呼叫各觀察者所提供的方法來實現。此種模式通常被用來實現事件處理系統。
簡單來說,觀察者模式就是定義了對象間的一種一對多的依賴關係,當一個對象的狀態發生改變時, 所有依賴於它的對象都得到通知並被自動更新。
結構
觀察者模式結構中通常包括觀察目標和觀察者兩個繼承階層,其結構:
觀察者模式定義了四種角色:抽象主題、具體主題、抽象觀察者、具體觀察者。
● Subject(目標):目標又稱為主題,它是指被觀察的對象。在目標中定義了一個觀察者集合,一個觀察目標可以接受任意數量的觀察者來觀察,它提供一系列方法來增加和刪除觀察者對象,同時它定義了通知方法notify()。目標類可以是介面,也可以是抽象類別或具體類。
● ConcreteSubject(具體目標):具體目標是目標類的子類,通常它包含有經常發生改變的資料,當它的狀態發生改變時,向它的各個觀察者發出通知;同時它還實現了在目標類中定義的抽象商務邏輯方法(如果有的話)。如果無須擴充目標類,則具體目標類可以省略。
● Observer(觀察者):觀察者將對觀察目標的改變做出反應,觀察者一般定義為介面,該介面聲明了更新資料的方法update(),因此又稱為抽象觀察者。
● ConcreteObserver(具體觀察者):在具體觀察者中維護一個指向具體目標對象的引用,它儲存具體觀察者的有關狀態,這些狀態需要和具體目標的狀態保持一致;它實現了在抽象觀察者Observer中定義的update()方法。通常在實現時,可以調用具體目標類的attach()方法將自己添加到目標類的集合中或通過detach()方法將自己從目標類的集合中刪除。
模式解析
在這個項目中定義了抽象觀察者介面(Observer),點擊查看Github源碼
package observer;/*** * *@Author ChenjunWang *@Description: 觀察者介面 *@Date: Created in 16:10 2018/4/11 *@Modified By: * */public interface Observer { void update(String msg);}
具體觀察者類(Client)如下,點擊查看Github源碼
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 + "號客戶,現在還沒到我了!"); } }}
定義抽象主題介面(Subject),點擊查看Github源碼
public interface Subject { //註冊觀察者 void registerObserver(Observer observer); //移除觀察者 void removeObserver(Observer observer); //提醒觀察者 void notifyObserver(String msg);}
定義具體主題(BankCallCenter)類,點擊查看Github源碼
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); }}
運行結果測試,點擊查看源碼
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("------------從觀察者列表中移除二號-----------"); }
銀行呼叫項目一共建4個類,其中2個是觀察者介面,和被觀察者介面,另外2個是實作類別,一個銀行話務中心和取了號的客戶。作出銀行呼叫項目的UML圖,更能看出觀察者模式的結構:
優缺點
好處:
1.被觀察者利用notifyObserver群發訊息,銀行呼叫項目在update方法中對接受到的訊息進行了處理,若收到有用的訊息則進行操作。
2.觀察者模式適合一個軟體系統要求在某一個對象狀態發生變化的時候,某些其他的對象作出相應的改變。觀察者模式減少對象之間的耦合有利於系統的複用。
3.銀行項目主體在發送呼叫通知的時候,無須指定具體的客戶,Observer可以自己決定是否要訂閱Bankcallcenter Subject的通知。
不足:
1.如果一個Bankcenter Subject被大量Client的Observer訂閱的話,在呼叫通知的時候可能會有效率問題。
2.不得不說使用了觀察者模式使得銀行呼叫項目代碼關係變得複雜。
銀行辦理業務觀察者模式解析