觀察者模式
觀察者模式:
定義物件之間一種一對多的關係,使得每當一個一個物件發生改變的時候,其相關依賴物件皆通知並且自動更改。
意圖 : 定義物件間的一種一對多的依賴關係,當一個物件的狀態發生改變時,所有依賴於它的物件都得到通知並被自動更新
主要解決 : 一個物件狀態改變給其他物件通知的問題,而且要考慮到易用和低耦合,保證高度的協作。
如何解決 : 使用面向物件技術,可以將這種依賴關係弱化。
關鍵程式碼 : 在抽象類裡有一個 ArrayList 存放觀察者們。
一個物件的狀態或者行為的變化,將導致對其他行為發生也發生變化,他們之間會陳勝聯動
在觀察者模式中,發生改變的物件稱為觀察目標,被通知的物件稱為觀察者
一個觀察目標可以對應多個觀察者
觀察者模式又稱釋出-訂閱模式,模型-檢視模式,源-監聽器模式,從屬者模式
Subject(目標):又稱為主題,是指觀察者的物件,在目標中定義一個集合,可以接受任意數量的觀察者,目標可以為抽象類。
ConcreteSubject(具體目標):是目標的子類,包含經常發生改變的資料,當狀態改變的時候,將向觀察者發出通知。
Observe(觀察者):將對具體目標做出反應,一般定義為介面,該介面聲明瞭一個更新資料的方法,又稱抽象觀察者。
ConcreteObserve(具體觀察者):在具體觀察者中維護和指向觀察者目標物件的引用,它儲存觀察者的某些狀態。
優點:
1、觀察者和被觀察者是抽象耦合的。
2、建立一套觸發機制。
缺點:
1、如果一個被觀察者物件有很多的直接和間接的觀察者的話,將所有的觀察者都通知到會花費很多時間。
2、如果在觀察者和觀察目標之間有迴圈依賴的話,觀察目標會觸發它們之間進行迴圈呼叫,可能導致系統崩潰。
3、觀察者模式沒有相應的機制讓觀察者知道所觀察的目標物件是怎麼發生變化的,而僅僅只是知道觀察目標發生了變化。
使用場景:
1.一個抽象模型有兩個方面,其中一個方面依賴於另一個方面。將這些方面封裝在獨立的物件中使它們可以各自獨立地改變和複用。
2.一個物件的改變將導致其他一個或多個物件也發生改變,而不知道具體有多少物件將發生改變,可以降低物件之間的耦合度。
3.一個物件必須通知其他物件,而並不知道這些物件是誰。
4.需要在系統中建立一個觸發鏈,A物件的行為將影響B物件,B物件的行為將影響C物件……,可以使用觀察者模式建立一種鏈式觸發機制。
程式碼設計:
subject.java
public class subject { private List<Observe> observes = new ArrayList<Observe>(); //新增 public void addObserve(Observe observe){ observes.add(observe); } //通知 public void notifys(){ for (Observe o : observes){ o.update(); } } }
Observe.java
public abstractclass Observe { protectedsubject subject; public abstractvoid update(); }
BusObserver1.java
public class BusObserver1 extends Observe { @Override public void update() { System.out.println("看到紅燈,減速停車Bus1"); } public BusObserver1(subject subject){ this.subject = subject; this.subject.addObserve(this); } }
BusObserver2.java
public class BusObserver2 extendsObserve { @Override public void update() { System.out.println("看到紅燈,減速停車Bus2"); } public BusObserver2(subject subject){ this.subject = subject; this.subject.addObserve(this); } }
測試:
public class test { public static void main(String[] args) { subject subject = new subject(); BusObserver1 binaryObserver = new BusObserver1(subject); BusObserver2 octalObserver = new BusObserver2(subject); System.out.println("紅燈..."); subject.notifys(); } }
結果:
紅燈... 看到紅燈,減速停車Bus1 看到紅燈,減速停車Bus2