首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

從 Java 類庫看設計模式(一):Observer 模式核心機制與 JDK 實作

     編輯:Java 相關知識

前言

設計模式是「特定情境下反覆出現問題的文檔化解決方案」。GoF 《設計模式》一書定義的 23 種模式奠基了軟體設計通用語言。本系列從 Java 類庫切入,首篇深度剖析 **Observer 模式** 在 JDK (java.util.Observable/Observer) 的實作細節與應用範例。

Observer 模式核心角色

  • Subject (Observable):被觀察者,狀態變更時通知觀察者。
  • Observer:觀察者,註冊至 Subject,接收通知並回應。

典型場景:UI 資料變更同步更新資料庫、資料庫變更自動刷新 UI。

JDK 內建實作

java.util.Observer 介面


public interface Observer {
    void update(Observable o, Object arg); // 狹義應呼叫 o.getX() 取最新狀態
}

java.util.Observable 類別

方法功能
addObserver(Observer)註冊觀察者至內部 Vector 列表
deleteObserver(Observer)移除單一觀察者
deleteObservers()清空所有觀察者
countObservers()返回註冊數量
setChanged()protected,標記狀態已變更(必須調用,否則通知不發送)
clearChanged()protected,清除變更標記(notifyObservers 內自動調用)
hasChanged()檢查是否已變更
notifyObservers(Object)檢查標記,若已變更則**同步**逐一呼叫 update(),最後清除標記
notifyObservers()等同 notifyObservers(null)

同步機制:notifyObservers 為 synchronized,多執行緒環境下順序執行,但可能導致新增觀察者遺漏通知、已移除觀察者仍收到通知。

應用範例:FrameSubject / FrameObserver


// Subject:封裝 Observable,轉發註冊與通知
class FrameSubject extends JFrame {
    DateSubject subject = new DateSubject(); // 繼承 Observable
    public void registerObserver(Observer o) { subject.addObserver(o); }
    void onButtonClick() {
        subject.setWidthInfo(parseInt(tf1.getText()));
        subject.setHeightInfo(parseInt(tf2.getText()));
        subject.notifyObservers(); // 發送通知
    }
}

// Observable 子類:封裝被觀察資料
class DateSubject extends Observable {
    private int width, height;
    public void setWidthInfo(int w) { width = w; setChanged(); } // 關鍵:setChanged()
    public void setHeightInfo(int h) { height = h; setChanged(); }
    public int getWidthInfo() { return width; }
    public int getHeightInfo() { return height; }
}

// Observer 實作:接收通知並更新 UI
class FrameObserver extends JFrame implements Observer {
    public void update(Observable o, Object arg) {
        DateSubject s = (DateSubject) o;
        lblWidth.setText(String.valueOf(s.getWidthInfo()));
        lblHeight.setText(String.valueOf(s.getHeightInfo()));
    }
}

// 啟動
FrameSubject f1 = new FrameSubject();
FrameObserver f2 = new FrameObserver();
f1.registerObserver(f2);
f1.setVisible(true); f2.setVisible(true);

JDK 實作評析

  • ✅ 類別 Observable 提供預設通知邏輯,簡化開發。
  • ✅ Vector 管理觀察者列表,符合大多數場景。
  • ❌ **類別而非介面**,限制多重繼承(範例中 FrameSubject 僅能組合而非繼承)。
  • ❌ 列表管理硬編碼於 Observable,複雜場景需自行抽離 Manager 類別解耦。

結語

Observer 模式解決物件間**狀態映射/鏡像**問題。JDK 內建實作足應付一般需求,但理解其限制(類別化、同步通知、列表耦合),在需要高擴展性時可自行實作介面化版本。掌握模式語言,能以最小認知負擔溝通複雜設計意圖。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved