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

Java 設計模式:享元模式(Flyweight Pattern)優化記憶體與性能

     編輯:Java 相關知識

什麼是享元模式?

享元模式屬於結構型模式,核心目標是通過共享技術有效地支持大量細粒度對象,避免大量相似對象的開銷(如內存消耗)。適用於「大量相似對象、狀態可分離」的場景。

核心概念:內部狀態 vs 外部狀態

  • 內部狀態:可共享、不隨環境變化的數據(如字符的字形、CD 的歌手名)。存儲於享元對象內,不可變。
  • 外部狀態:不可共享、隨環境變化的數據(如字符的位置、CD 的標題/年份)。由客戶端維护,調用時傳入。

模式結構

  • Flyweight(抽象享元):定義操作介面,接收外部狀態參數。
  • ConcreteFlyweight(具體享元):實現介面,存儲內部狀態,線程安全。
  • UnsharedConcreteFlyweight(非共享享元):不需共享的對象,直接實現介面。
  • FlyweightFactory(享元工廠):管理享元池,提供 getFlyweight(key) 獲取/創建共享對象。

代碼實戰:CD 收藏管理

場景:數萬張 CD,歌手名大量重複。將「歌手」作為享元共享。

// 1. 內部狀態:歌手(不可變,可共享)
class Artist {
    private final String name; // 內部狀態
    public Artist(String name) { this.name = name; }
    public String getName() { return name; }
}

// 2. 享元工廠:管理歌手池
class ArtistFactory {
    private Map pool = new HashMap<>();
    public Artist getArtist(String name) {
        return pool.computeIfAbsent(name, Artist::new);
    }
}

// 3. 外部狀態:CD 標題、年份(不共享)
class CD {
    private String title;
    private int year;
    private Artist artist; // 引用共享歌手
    // getter/setter...
}

// 4. 使用
ArtistFactory factory = new ArtistFactory();
CD cd1 = new CD("Album1", 2000, factory.getArtist("Jay Chou"));
CD cd2 = new CD("Album2", 2005, factory.getArtist("Jay Chou")); // 同一 Artist 實例
System.out.println(cd1.getArtist() == cd2.getArtist()); // true,節省內存

XML 數據解析場景

解析大量 XML 記錄時,重複字符串(如標籤名、枚舉值)可放入享元池,顯著降低內存佔用,提升解析速度。

優缺點與注意點

優點缺點/注意
大幅減少對象數量,降低內存增加系統複雜度(需分離狀態)
提升性能(減少 GC、提高緩存命中)運行時查找/傳遞外部狀態有微小開銷
內部狀態不可變,天然線程安全適用於「大量相似、狀態可分離」場景,濫用反增複雜度

Java 標準庫應用

  • Integer.valueOf(-128~127) 緩存池。
  • String.intern() 字符串常量池。
  • Boolean.valueOf() 只返回兩個實例。

享元模式是「空間換時間」的經典體現,大數據、高併發場景下極具價值。

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