1、定義與組成部分設計模式
定義異步
觀察者(Observer)模式 又名發佈-訂閱(Publish/Subscribe)模式。GOF 給觀察者模式以下定義:ide
定義對象間的一種一對多的依賴關係,當一個對象的狀態發生改變時,全部依賴於它的對象都獲得通知並被自動更新。
面向對象設計的一個重要原則——單一職責原則。系統的每一個對象應該將重點放在問題域中的離散抽象上。所以理想的狀況下,一個對象只作一件事情。這樣在開發中也就帶來了諸多的好處:提供了重用性和維護性,也是進行重構的良好的基礎。測試
組成部分
觀察者模式由如下幾部分組成:
抽象目標角色(Subject):目標角色知道它的觀察者,能夠有任意多個觀察者觀察同一個目標。而且提供註冊和刪除觀察者對象的接口。目標角色每每由抽象類或者接口來實現。
抽象觀察者角色(Observer):爲那些在目標發生改變時須要得到通知的對象定義一個更新接口。抽象觀察者角色主要由抽象類或者接口來實現。
具體目標角色(Concrete Subject):將有關狀態存入各個Concrete Observer 對象。當它的狀態發生改變時, 向它的各個觀察者發出通知。
具體觀察者角色(Concrete Observer):存儲有關狀態,這些狀態應與目標的狀態保持一致。實現Observer 的更新接口以使自身狀態與目標的狀態保持一致。在本角色內也能夠維護一個指向Concrete Subject 對象的引用。
使用觀察者模式的類圖,這樣能將關係清晰的表達出來。
在 Subject 這個抽象類中,提供了上面提到的功能,並且存在一個通知方法:notify。
還能夠看到Subject 和ConcreteSubject 之間能夠說是使用了模板模式(這個模式真是簡單廣泛到一不當心就用到了)。
這樣當具體目標角色的狀態發生改變,按照約定則會去調用通知方法,在這個方法中則會根據目標角色中註冊的觀察者名單來逐個調用相應的update 方法來調整觀察者的狀態。
這樣觀察者模式就走完了一個流程。
2、實現觀察者模式
MySubject類就是咱們的主對象,Observer1和Observer2是依賴於MySubject的對象,當MySubject變化時,Observer1和Observer2必然變化。
AbstractSubject類中定義着須要監控的對象列表,能夠對其進行修改:增長或刪除被監控對象,且當MySubject變化時,負責通知在列表內存在的對象。
Observer接口:
public interface Observer {
public void update();
}
實現類:Observer1
public class Observer1 implements Observer {br/>@Override
public void update() {
System.out.println("observer1 接收到了!");
}
}
實現類:Observer2
public class Observer2 implements Observer{br/>@Override
public void update() {
System.out.println("observer2 接收到了!");
}
}
Subject接口
public interface Subject {設計
/**server
/**對象
/**blog
/**接口
@Override
public void add(Observer observer) {
vector.add(observer);
}內存
@Override
public void del(Observer observer) {
vector.remove(observer);
}
@Override
public void notifyObservers() {
Enumeration<Observer> enumo = vector.elements();
while (enumo.hasMoreElements()) {
enumo.nextElement().update();
}
}
@Override
public void operation() {
}
}
MySubject類
public class MySubject extends AbstractSubject {br/>@Override
public void operation() {
System.out.println("主對象的狀態發生了改變!");
notifyObservers();
}
}
測試類:
public class Test {
public static void main(String[] args) {
Subject subject = new MySubject();
subject.add(new Observer1());
subject.add(new Observer2());
subject.operation();
}
}
測試結果:3、 總結1.觀察者模式 主要解決了什麼問題?一個對象狀態改變給其餘對象通知的問題,並且要考慮到易用和低耦合,保證高度的協做。2.如何解決?使用面向對象技術,能夠將這種依賴關係弱化。3.觀察者模式 什麼時候使用?一個對象(目標對象)的狀態發生改變,全部的依賴對象(觀察者對象)都將獲得通知,進行廣播通知。4.觀察者模式 的優缺點【優勢】① 觀察者和被觀察者是抽象耦合的。② 創建一套觸發機制。【缺點】① 若是一個被觀察者對象有不少的直接和間接的觀察者的話,將全部的觀察者都通知到會花費不少時間。②若是在觀察者和觀察目標之間有循環依賴的話,觀察目標會觸發它們之間進行循環調用,可能致使系統崩潰。③ 觀察者模式沒有相應的機制讓觀察者知道所觀察的目標對象是怎麼發生變化的,而僅僅只是知道觀察目標發生了變化。5.觀察者模式 的使用場景一個抽象模型有兩個方面,其中一個方面依賴於另外一個方面。將這些方面封裝在獨立的對象中使它們能夠各自獨立地改變和複用。一個對象的改變將致使其餘一個或多個對象也發生改變,而不知道具體有多少對象將發生改變,能夠下降對象之間的耦合度。一個對象必須通知其餘對象,而並不知道這些對象是誰。須要在系統中建立一個觸發鏈,A對象的行爲將影響B對象,B對象的行爲將影響C對象……,可使用觀察者模式建立一種鏈式觸發機制。6.觀察者模式 的注意事項① JAVA 中已經有了對觀察者模式的支持類。② 避免循環引用。③ 若是順序執行,某一觀察者錯誤會致使系統卡殼,通常採用異步方式。