【程式碼簡述設計模式】----- 觀察者模式
阿新 • • 發佈:2019-06-15
什麼是觀察者模式
觀察者模式:定義物件之間的一對多依賴,當一個物件的改變狀態時,它的依賴者都會收到通知並自動更新。這裡就用報社、人來分析,如果有人想看報紙就可以向報社訂閱,如果已經訂閱的人不想看報紙可以向報社登出,而對於報社而言,它只會把報紙發給訂閱的人群,這裡的報社就是觀察者模式中的主題(Subject),人就是觀察者(Observer),觀察者向主題註冊自己就可以在主題改變時收到通知。
觀察者模式UML圖
程式碼實現
/** * 觀察者模式的主題,用於註冊、移除、通知觀察者 */ public interface Subject { /** * 新增觀察者 */ void registerObserver(Observer observer); /** * 移除觀察者 */ void removeObserver(Observer observer); /** * 通知觀察者 */ void notifyObserver(String newspaperName); } /** * 觀察者介面類 */ public interface Observer { /** * 被通知時做的操作 */ void update(String newspaperName); }
上面時觀察者模式的兩個核心類,下面時具體的應用,首先是主題實現類-NewspaperOffice,observerList 儲存所有的觀察者,
import java.util.ArrayList; import java.util.List; public class NewspaperOffice implements Subject{ private List<Observer> observerList = new ArrayList<>(); @Override public void registerObserver(Observer observer) { observerList.add(observer); } @Override public void removeObserver(Observer observer) { observerList.remove(observer); } /** * 通知觀察者們 */ @Override public void notifyObserver(String newspaperName) { observerList.forEach((b) -> b.update(newspaperName)); } }
這裡是具體的觀察者,也就是被通知的物件
/** * 觀察者A */ public class CustomerA implements Observer{ private Subject subject; public CustomerA(Subject subject) { this.subject = subject; subject.registerObserver(this); } @Override public void update(String newspaperName) { System.out.println("CustomerA:《" + newspaperName + "》釋出了"); } } /** * 觀察者B */ public class CustomerB implements Observer { private Subject subject; public CustomerB(Subject subject) { this.subject = subject; subject.registerObserver(this); } @Override public void update(String newspaperName) { System.out.println("CustomerB:《" + newspaperName + "》釋出了"); } }
測試上面寫的簡易觀察者模式實現
public class ObserverTest {
public static void main(String[] args) {
Subject subject = new NewspaperOffice();
new CustomerA(subject);
// 註冊觀察者B
new CustomerB(subject);
// 通知觀察者們
subject.notifyObserver("日報A");
System.out.println("========================================");
subject.notifyObserver("日報B");
}
}
測試結果
總結
從上面的例子分析,主題和觀察則都是介面,主題通過介面通知依賴它的所有觀察者做某個操作(廣播通訊),只要知道具體物件的列表,而不需要知道某個具體的物件,上面例子NewspaperOffice只需擁有Observer陣列,至於具體的某個Observer並不關注,降低了物件之間的耦合度,這裡也是設計原則"針對介面程式設計,不針對實現程式設計"的體現