1. 程式人生 > 實用技巧 >申請jetbrains使用許可權(教育郵箱)

申請jetbrains使用許可權(教育郵箱)

觀察者模式

(有時又被稱為模型(Model)-檢視(View)模式、源-收聽者(Listener)模式或從屬者模式)

觀察者模式還有一個名字叫釋出-訂閱模式,我們熟悉的訊息佇列如ActiveMQ,就是採用的這種設計模式

當物件間存在一對多關係時,則使用觀察者模式(Observer Pattern)。比如,當一個物件被修改時,則會自動通知依賴它的物件。觀察者模式屬於行為型模式。

介紹

意圖:定義物件間的一種一對多的依賴關係,當一個物件的狀態發生改變時,所有依賴於它的物件都得到通知並被自動更新。

主要解決:一個物件狀態改變給其他物件通知的問題,而且要考慮到易用和低耦合,保證高度的協作。

何時使用:

一個物件狀態改變,所有的依賴物件都將得到通知。

關鍵程式碼:在抽象類裡有一個 ArrayList 存放觀察者們。

優點:1、觀察者和被觀察者是抽象耦合的。 2、建立一套觸發機制。

缺點:1、如果一個被觀察者物件有很多的直接和間接的觀察者的話,將所有的觀察者都通知到會花費很多時間。 2、如果在觀察者和觀察目標之間有迴圈依賴的話,觀察目標會觸發它們之間進行迴圈呼叫,可能導致系統崩潰。 3、觀察者模式沒有相應的機制讓觀察者知道所觀察的目標物件是怎麼發生變化的,而僅僅只是知道觀察目標發生了變化。

使用場景:

  • 一個抽象模型有兩個方面,其中一個方面依賴於另一個方面。將這些方面封裝在獨立的物件中使它們可以各自獨立地改變和複用。
  • 一個物件的改變將導致其他一個或多個物件也發生改變,而不知道具體有多少物件將發生改變,可以降低物件之間的耦合度。
  • 一個物件必須通知其他物件,而並不知道這些物件是誰。
  • 需要在系統中建立一個觸發鏈,A物件的行為將影響B物件,B物件的行為將影響C物件……,可以使用觀察者模式建立一種鏈式觸發機制。

注意事項:1、JAVA 中已經有了對觀察者模式的支援類。 2、避免迴圈引用。 3、如果順序執行,某一觀察者錯誤會導致系統卡殼,一般採用非同步方式。

(1)Subject:抽象主題,他把所有觀察者物件儲存在一個集合裡,可以有任意數量的觀察者,抽象主題提供一個介面,可以增加和刪除觀察者物件。意思就是明星把所有的粉絲都儲存在一個賬號裡面,粉絲數量不限,可以新增粉絲也可以拉黑粉絲。

(2)Observer:抽象觀察者,是觀察者者的抽象類,它定義了一個更新介面,使得在得到主題更改通知時更新自己。這就是我們所有粉絲的抽象。

(3)ConcrereObserver:具體觀察者,實現抽象觀察者定義的更新介面,以便在得到主題更改通知時更新自身的狀態。具體每一個粉絲。

實現

步驟 1

/*
主題Subject
 */
import java.util.*;

public class Subject {
    //觀察者陣列
    private List<Observer> observers
            = new ArrayList<Observer>();

   //增加一個觀察者
    public void addObserver(Observer observer)
    {
        this.observers.add(observer);
    }
     //刪除一個觀察者
     public void deleteObserver(Observer observer)
     {

         this.observers.remove(observer);
     }
     //通知所有觀察者
     public void notifyAllObservers(String msg){
         for (Observer observer : observers) {
             observer.update(msg);
         }
     }
}

步驟 2

/*
觀察者Observer
 */
public abstract class Observer {
    protected Subject subject;
    public abstract void update(String msg);
}

步驟 3

/*
具體觀察者
 */
public class ConcreteObserver extends  Observer {

    private  String name;
    public ConcreteObserver(String name)
    {
        this.name=name;
    }

    @Override
    public void update(String msg) {
        System.out.println(name+"收到訊息"+msg);
    }
}

步驟 4

/*
觀察者模式(Observer Pattern)
使用 Subject 和實體觀察者物件。
 */
public class ObserverPatternDescription {

    public static void main(String[] args) {
        Subject subject = new Subject();
        //定義一個觀察者
        Observer observer=new ConcreteObserver("小李");
        Observer observer2=new ConcreteObserver("小紅");
        Observer observer3=new ConcreteObserver("小明");
        //觀察
        subject.addObserver(observer);
        subject.addObserver(observer2);
        subject.addObserver(observer3);
        //開始活動
        subject.notifyAllObservers("處理中。。。");
    }
}

結果

小李收到訊息處理中。。。
小紅收到訊息處理中。。。
小明收到訊息處理中。。。