Java程式員從笨鳥到菜鳥之(三十六)大話設計模式(六)觀察者模式

來源:互聯網
上載者:User

本文來自:曹勝歡部落格專欄。轉載請註明出處:http://blog.csdn.net/csh624366188        

 

         Observer模式是行為模式之一,它的作用是當一個對象的狀態發生變化時,能夠自動通知其他關聯對象,自動重新整理對象狀態。Observer模式提供給關聯對象一種同步通訊的手段,使某個對象與依賴它的其他對象之間保持狀態同步。《設計模式》一書對Observer是這樣描述的:定義對象間的一種一對多的依賴關係,當一個對象的狀態發生改變時,所有依賴於它的對象都將得到通知並自動更新。別名:依賴(Dependents)、發布-訂閱(Publish-Subscribe)。

下面我們就來看看觀察者模式的組成部分。

1) 抽象目標角色(Subject):目標角色知道它的觀察者,可以有任意多個觀察者觀察同一個目標。並且提供註冊和刪除觀察者對象的介面。目標角色往往由抽象類別或者介面來實現。

2) 抽象觀察者角色(Observer):為那些在目標發生改變時需要獲得通知的對象定義一個更新介面。抽象觀察者角色主要由抽象類別或者介面來實現。

3)具體目標角色(Concrete Subject):將有關狀態存入各個Concrete Observer對象。當它的狀態發生改變時, 向它的各個觀察者發出通知。

4) 具體觀察者角色(Concrete Observer):儲存有關狀態,這些狀態應與目標的狀態保持一致。實現Observer的更新介面以使自身狀態與目標的狀態保持一致。在本角色內也可以維護一個指向Concrete Subject對象的引用。

結構如下:

觀察者模式的優缺點:

觀察者模式的效果有以下的優點:

  第一、觀察者模式在被觀察者和觀察者之間建立一個抽象的耦合。被觀察者角色所知道的只是一個具體觀察者列表,每一個具體觀察者都符合一個抽象觀察者的介面。被觀察者並不認識任何一個具體觀察者,它只知道它們都有一個共同的介面。

  由於被觀察者和觀察者沒有緊密地耦合在一起,因此它們可以屬於不同的抽象化層次。如果被觀察者和觀察者都被扔到一起,那麼這個對象必然跨越抽象化和具體化層次。

  第二、觀察者模式支援廣播通訊。被觀察者會向所有的登記過的觀察者發出通知,

觀察者模式有下面的缺點:

第一、如果一個被觀察者對象有很多的直接和間接的觀察者的話,將所有的觀察者都通知到會花費很多時間。
第二、如果在被觀察者之間有循環相依性的話,被觀察者會觸發它們之間進行迴圈調用,導致系統崩潰。在使用觀察者模式是要特別注意這一點。
第三、如果對觀察者的通知是通過另外的線程進行非同步投遞的話,系統必須保證投遞是以自恰的方式進行的。
第四、雖然觀察者模式可以隨時使觀察者知道所觀察的對象發生了變化,但是觀察者模式沒有相應的機制使觀察者知道所觀察的對象是怎麼發生變化的。

下面用程式來說明一下觀察者模式的流程:

一個隨機數產生對象和兩個觀察者,這兩個觀察者都在隨機數產生對象那裡註冊了,意思說如果你產生了新的數字,就通知我一聲。

 

結構圖:

類說明 

 名稱

 功能說明

 Observer

 表示觀察者的介面,要成為觀察者必須實現此介面才行

 NumberGenerator

 表示產生數值的抽象類別

 RandomNumberGenerator

 產生隨機數的類,繼承於NumberGenerator

 NumberObserver

 數字觀察者,會列印出變化的數字

 SymbolObserver

 符號觀察者,列印N 個符號,列印多少個符號,由接受到的數值確定

 

1.Observer

package com.pattern.observer;public interface Observer {public abstract void update(NumberGenerator generator);}

2.NumberGenerator

 

package com.pattern.observer;import java.util.ArrayList;import java.util.Iterator;/** * @project JavaPattern * @author sunnylocus * @verson 1.0.0 * @date   Aug 27, 2008 1:35:34 PM * @description 產生數值的抽象類別 */public abstract class NumberGenerator {private ArrayList observers = new ArrayList();  //儲存Observer/** 添加觀察者*/public void addObserver(Observer observer) {observers.add(observer);}/** 刪除觀察者*/public void delObserver(Observer observer) {observers.remove(observer);}/** 通知所有觀察者*/public void notifyObservers() {Iterator it = observers.iterator();while(it.hasNext()) {Observer o =(Observer) it.next();o.update(this);//this相當於上面提到的郵局名}}public abstract int getNumber();//擷取數字public abstract void generate();//產生數字}

3.RandomNumberGenerator

package com.pattern.observer;import java.util.Random;/** * @project JavaPattern * @author sunnylocus * @verson 1.0.0 * @date   Aug 27, 2008 1:48:03 PM * @description 用於產生隨機數及通知觀察者的類 */public class RandomNumberGenerator extends NumberGenerator{private Random random = new Random();//隨機數產生器private int number;   //用於存放數字public void generate() {for(int i=0 ; i < 5; i++) {number = random.nextInt(10);//產生10以內的隨機數notifyObservers();  //有新產生的數字,通知所有註冊的觀察者}}    /** 獲得數字*/public int getNumber() {return number;}}

4.NumberObserver

 package com.pattern.observer;/** 以數字表示觀察者的類*/public class NumberObserver implements Observer{public void update(NumberGenerator generator) {System.out.println("NumberObserver:"+ generator.getNumber());try {Thread.sleep(1000 * 3); //為了能清楚的看到輸出,休眠3秒鐘。}catch(InterruptedException e) {e.printStackTrace();}}}

5.SymbolObserver

package com.pattern.observer;/** 以符號表示觀察者的類*/public class SymbolObserver implements Observer{public void update(NumberGenerator generator) {System.out.print("SymbolObserver:");int count = generator.getNumber();for(int i = 0 ; i < count; i ++) {System.out.print("*^_^*  ");}System.out.println("");try {Thread.sleep(1000 * 3);}catch(InterruptedException e){e.printStackTrace();}}}

6.Main(測試類別) 

package com.pattern.observer;public class Main {public static void main(String[] args) {//執行個體化數字產生對象NumberGenerator generator = new RandomNumberGenerator();//執行個體化觀察者Observer observer1 = new NumberObserver();Observer observer2 = new SymbolObserver();//註冊觀察者generator.addObserver(observer1);generator.addObserver(observer2);generator.generate(); //產生數字}}

 7.結果輸出

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.