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

Java 設計模式:虛擬代理模式 —— 延遲載入重量級物件的記憶體優化術

     編輯:Java 相關知識

模式動機

應用啟動時,某些功能物件(大型圖片、複雜報表引擎、Javadoc 生成器)佔用大量記憶體/啟動緩慢,但使用者可能**從未使用**該功能。虛擬代理建議:**等到真正需要時才建立真實物件**。

結構角色

  • Subject (介面/抽象類): 定義真實物件與代理共同介面。
  • RealSubject: 真正執行工作的重量級物件。
  • Proxy: 持有 RealSubject 參考,控制存取,負責延遲建立。

優缺點權衡

優點缺點
加快啟動速度、降低初始記憶體佔用 每次存取前需檢查 null,增加微小開銷與代碼複雜度
客戶端無感知,介面一致 首次使用會有建立延遲(可用背景執行緒預載緩解)

實戰範例:IDE 三大功能 —— 編譯、執行、產生 Javadoc

共同介面

public abstract class IDEOperation {
    private final Compiler compiler = new Compiler();
    private final Runtime runtime = new Runtime();

    public void compile(String javaFile) { compiler.compile(javaFile); }
    public void run(String classFile) { runtime.run(classFile); }

    // 抽象方法:由具體實現決定何時建立 Javadoc 物件
    public abstract void generateDocs(String javaFile);
}

真實實現(啟動即建立 Javadoc 物件)

public class RealProcessor extends IDEOperation {
    private final JavaDoc jdoc = new JavaDoc(); // 啟動時建立,佔記憶體
    @Override
    public void generateDocs(String javaFile) { jdoc.generateDocs(javaFile); }
}

虛擬代理實現(延遲建立)

public class ProxyProcessor extends IDEOperation {
    private RealProcessor realProcessor; // 初始為 null

    @Override
    public void generateDocs(String javaFile) {
        if (realProcessor == null) {        // 1. 首次呼叫時建立
            realProcessor = new RealProcessor();
        }
        realProcessor.generateDocs(javaFile); // 2. 轉發呼叫
    }
}

客戶端使用

public class Client {
    public static void main(String[] args) {
        IDEOperation ide = new ProxyProcessor(); // 輕量啟動
        ide.compile("Test.java");                // 直接用 compiler/runtime
        ide.run("Test.class");
        // ... 使用者工作一段時間 ...
        ide.generateDocs("Test.java");           // 首次需要時才載入 Javadoc 引擎
    }
}

關鍵實現細節

  1. 代理與真實物件實作相同介面,客戶端面向介面編程,完全不知情。
  2. 代理持有真實物件引用,首次 null 檢查後建立並快取,後續直接轉發。
  3. 建立邏輯封裝在代理內部,客戶端不需關心生命週期。
  4. 多執行緒環境下,建立檢查需加雙重檢查鎖或 synchronized 確保單例。

常見應用場景

  • 圖片瀏覽器: 縮圖先顯示,點擊大圖時才載入高解析度檔案。
  • 資料庫連線池: 啟動建立最小連線,負載增大時動態擴充。
  • 大型報表/匯出引擎: 僅在使用者點擊「匯出」時載入 POI/iText 等重型庫。
  • Spring AOP / Hibernate 延遲載入: 框架層面大量應用代理模式。

總結

虛擬代理是空間換時間、啟動換首次延遲的經典策略。正確識別「重量級、低頻率、非必要」的物件套用此模式,能顯著提升應用啟動體驗與記憶體效率。

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