1. 程式人生 > >【程式碼簡述設計模式】----- 觀察者模式

【程式碼簡述設計模式】----- 觀察者模式

什麼是觀察者模式

 觀察者模式:定義物件之間的一對多依賴,當一個物件的改變狀態時,它的依賴者都會收到通知並自動更新。這裡就用報社、人來分析,如果有人想看報紙就可以向報社訂閱,如果已經訂閱的人不想看報紙可以向報社登出,而對於報社而言,它只會把報紙發給訂閱的人群,這裡的報社就是觀察者模式中的主題(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並不關注,降低了物件之間的耦合度,這裡也是設計原則"針對介面程式設計,不針對實現程式設計"的體現