觀察者模式Java詳解

一、觀察者模式Java

觀察者模式也稱為發布-訂閱模式,它是一種行為型設計模式,可實現對象之間的松耦合。在觀察者模式中,一個對象(主題)維護著一系列依賴於它(觀察者)的對象,當狀態發生改變時,主題會通知所有觀察者自動進行更新。

public interface Observer {
    void update();
}

public interface Subject {
    void registerObserver(Observer observer);
    void removeObserver(Observer observer);
    void notifyObservers();
}

public class ConcreteSubject implements Subject {
    private List observers = new ArrayList();
    private int state;

    public void setState(int state) {
        this.state = state;
        notifyObservers();
    }

    public void registerObserver(Observer observer) {
        observers.add(observer);
    }

    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }

    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update();
        }
    }
}

public class ConcreteObserver implements Observer {
    private ConcreteSubject subject;

    public ConcreteObserver(ConcreteSubject subject) {
        this.subject = subject;
        subject.registerObserver(this);
    }

    public void update() {
        //do something
    }
}

public class Client {
    public static void main(String[] args) {
        ConcreteSubject subject = new ConcreteSubject();
        ConcreteObserver observer1 = new ConcreteObserver(subject);
        ConcreteObserver observer2 = new ConcreteObserver(subject);
        ConcreteObserver observer3 = new ConcreteObserver(subject);

        subject.setState(1);
    }
}

在上述代碼中,Observable介面是觀察者所需要實現的介面。Subject介面是主題所需要實現的介面。具體主題(ConcreteSubject)實現了Subject介面,並維護了一個觀察者列表。具體觀察者(ConcreteObserver)實現了Observer介面。

二、觀察者模式多對多

在觀察者模式中,主題和觀察者是一對多的關係,但是在實際應用中,有時候需要支持多對多的關係。

這時候需要在Subject介面中新增方法,讓觀察者可以取消訂閱,同時在具體觀察者中也可以新增註冊、註銷方法。

public interface Observer {
    void update();
    void subscribe(Subject subject);
    void unsubscribe(Subject subject);
}

public interface Subject {
    void registerObserver(Observer observer);
    void removeObserver(Observer observer);
    void notifyObservers();
    void registerSubject(Observer observer);
    void removeSubject(Observer observer);
}

public class ConcreteSubject implements Subject {
    private List observers = new ArrayList();
    private List subjects = new ArrayList();
    private int state;

    public void setState(int state) {
        this.state = state;
        notifyObservers();
    }

    public void registerObserver(Observer observer) {
        observers.add(observer);
    }

    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }

    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update();
        }
    }

    public void registerSubject(Observer observer) {
        subjects.add(observer);
    }

    public void removeSubject(Observer observer) {
        subjects.remove(observer);
    }
}

public class ConcreteObserver implements Observer {
    private ConcreteSubject subject;

    public void subscribe(Subject subject) {
        subject.registerSubject(this);
    }

    public void unsubscribe(Subject subject) {
        subject.removeSubject(this);
    }
}

public class Client {
    public static void main(String[] args) {
        ConcreteSubject subject1 = new ConcreteSubject();
        ConcreteSubject subject2 = new ConcreteSubject();
        ConcreteObserver observer1 = new ConcreteObserver();
        ConcreteObserver observer2 = new ConcreteObserver();
        observer1.subscribe(subject1);
        observer1.subscribe(subject2);
        observer2.subscribe(subject1);
    }
}

三、觀察者模式和狀態模式的區別

觀察者模式和狀態模式都是行為型模式,但它們的目的和結構是不同的。觀察者模式是用於對象間的通知,當一個對象的狀態發生變化時,它的所有依賴對象都會得到通知,並自動更新。而狀態模式是為了讓對象在不同情況下可以改變它的行為,實現狀態與行為的分離。

觀察者模式由主題和觀察者組成,主題維護一個觀察者列表,當狀態發生改變時通知觀察者。狀態模式由狀態、上下文和行為組成,行為的結果取決於上下文狀態的改變。

四、觀察者模式類圖

觀察者模式的類圖如下:

五、觀察者模式應用場景

觀察者模式適用於以下場景:

  • 當一個對象的改變必須要通知其他對象,並且不能假定那些對象是誰。
  • 當一個對象需要確保其他對象與之保持一致性時,如資料庫的一部分改變,需要通知其他部分進行更新操作。
  • 當一個對象改變時需要改變其他對象。
  • 當一個對象的改變需要其他對象反過來改變時,如遊戲中的人物狀態變化,會影響其他人物的狀態。

六、觀察者模式適用於

觀察者模式適用於Java中的Swing庫中的Model-View-Controller(MVC)模式,當Model的狀態發生改變時,View會自動得到通知進行更新。

七、觀察者模式的實現

觀察者模式的實現需要注意以下幾點:

  • 主題和觀察者之間的耦合度,需要注意避免循環依賴。
  • 代碼實現需要考慮線程安全問題。

八、觀察者模式觀察者太多

當觀察者過多時,會影響性能。解決方案可以是採取緩存機制,只更新最近使用的觀察者。

九、觀察者模式優缺點

觀察者模式的優點:

  • 分離了主題和觀察者的耦合,主題只需要知道觀察者實現了Observer介面即可,而不需要知道具體實現。
  • 主題可以通知多個觀察者進行更新,實現了松耦合。
  • 可以動態地添加和刪除觀察者。

觀察者模式的缺點:

  • 觀察者過多時,會影響性能。
  • 觀察者並不知道彼此的存在,容易導致程序出錯。

十、小結

觀察者模式Java是一種非常有用的設計模式,在Java中有廣泛的應用。通過觀察者模式,可以避免對象之間的耦合度,實現松耦合,增加程序的靈活性和可擴展性。在使用觀察者模式時,需要注意避免循環依賴和線程安全問題。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/271443.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-16 14:55
下一篇 2024-12-16 14:55

相關推薦

  • Java JsonPath 效率優化指南

    本篇文章將深入探討Java JsonPath的效率問題,並提供一些優化方案。 一、JsonPath 簡介 JsonPath是一個可用於從JSON數據中獲取信息的庫。它提供了一種DS…

    編程 2025-04-29
  • java client.getacsresponse 編譯報錯解決方法

    java client.getacsresponse 編譯報錯是Java編程過程中常見的錯誤,常見的原因是代碼的語法錯誤、類庫依賴問題和編譯環境的配置問題。下面將從多個方面進行分析…

    編程 2025-04-29
  • Java Bean載入過程

    Java Bean載入過程涉及到類載入器、反射機制和Java虛擬機的執行過程。在本文中,將從這三個方面詳細闡述Java Bean載入的過程。 一、類載入器 類載入器是Java虛擬機…

    編程 2025-04-29
  • Java騰訊雲音視頻對接

    本文旨在從多個方面詳細闡述Java騰訊雲音視頻對接,提供完整的代碼示例。 一、騰訊雲音視頻介紹 騰訊雲音視頻服務(Cloud Tencent Real-Time Communica…

    編程 2025-04-29
  • Java Milvus SearchParam withoutFields用法介紹

    本文將詳細介紹Java Milvus SearchParam withoutFields的相關知識和用法。 一、什麼是Java Milvus SearchParam without…

    編程 2025-04-29
  • Java 8中某一周的周一

    Java 8是Java語言中的一個版本,於2014年3月18日發布。本文將從多個方面對Java 8中某一周的周一進行詳細的闡述。 一、數組處理 Java 8新特性之一是Stream…

    編程 2025-04-29
  • Java判斷字元串是否存在多個

    本文將從以下幾個方面詳細闡述如何使用Java判斷一個字元串中是否存在多個指定字元: 一、字元串遍歷 字元串是Java編程中非常重要的一種數據類型。要判斷字元串中是否存在多個指定字元…

    編程 2025-04-29
  • VSCode為什麼無法運行Java

    解答:VSCode無法運行Java是因為默認情況下,VSCode並沒有集成Java運行環境,需要手動添加Java運行環境或安裝相關插件才能實現Java代碼的編寫、調試和運行。 一、…

    編程 2025-04-29
  • Java任務下發回滾系統的設計與實現

    本文將介紹一個Java任務下發回滾系統的設計與實現。該系統可以用於執行複雜的任務,包括可回滾的任務,及時恢復任務失敗前的狀態。系統使用Java語言進行開發,可以支持多種類型的任務。…

    編程 2025-04-29
  • Java 8 Group By 會影響排序嗎?

    是的,Java 8中的Group By會對排序產生影響。本文將從多個方面探討Group By對排序的影響。 一、Group By的概述 Group By是SQL中的一種常見操作,它…

    編程 2025-04-29

發表回復

登錄後才能評論