詳解Java設計模式編程中的Flyweight享元模式的開發結構_java

來源:互聯網
上載者:User

享元(Flyweight)模式:通過共用技術以便有效支援大量細粒度的對象。
享元模式在閻宏的《java與模式》中分為單純享元模式和複合享元模式,複合模式的複合享元是不可以共用的,享元對象能做到共用的關鍵是區分內蘊態(Internal State)和外蘊態( External State)。這兩個“蘊態”翻譯的太難懂,我不是說翻譯的不好,可能是我理解能力差,還是《Design Pattern Elements of Reusable Object-Oriented Software》的翻譯版《設計模式可複用物件導向軟體的基礎》一書總翻譯為內部對象和外部對象,相對直白,對概念性的東西文學氣味太強了就覺得很彆扭。這裡的角色也採用《設計模式可複用物件導向軟體的基礎》的說法,不區分單純模式和複合模式,而是有一個UnSharedConcreteFlyweight(在《java與模式》裡稱複合享元,指明複合享元不能共用),我們這裡稱它不可以共用享元角色,這樣享元模式的角色有:

  • 抽象享元(Flyweight)角色:是給實現享元提供的介面。
  • 具體享元(ConcreteFlyweight)角色:實現抽象角色,此對象必須是共用的,所含的狀態必須是內部狀態。
  • 不共用享元(UnSharedConcreteFlyweight)角色:此對象不可共用,不是所有實現抽象享元介面的的對象都要共用,此對象通常將ConcreteFlyweight作為組成元素。
  • 享元工廠(FlyweightFactory)角色:負責建立和管理享元角色,確保合理共用。
  • 用戶端(Client)角色:維持一個Flyweight對象的引用,計算或儲存一個(多個)外部儲存狀態。

享元模式的類的機構圖如下:

享元模式在java.lang.String設計上的使用,我們知道java中字串始終保持共用一份,如下面程式碼片段:

String m = "a";String n = "a";System.out.println(m==n);

這樣會輸出true,說明m和n指向了同一個執行個體,記憶體中也只有一個"a"。這就是享元模式在String上的使用。
 
享元模式在文字編輯存貯過程中的使用,這裡假定文章由行對象組成,行對象由若干個字元對象組成,但是如果每個字元都儲存自己的對象,那麼一篇文章成千上萬個字元對象,這樣嚴重消耗系統記憶體,造成不可接受的運行時開銷,好的方法是利用享元模式,只儲存ASCII字元編碼值,作為內部不變的狀態,對當個字元對象進行共用,而相對字元顏色、大小這樣的格式化資料作為外部狀態,由用戶端維護,運行時由外部傳入即可。每個行作為不可共用享元對象,它是由享元對象(字元對象)組合而成的。

我們來看個簡單地享元模式的結構的例子:

/**  * 字母  */ public class Letter {   private String name;   public Letter(String name) {   this.name = name;  }   public String getName() {   return name;  } } 
/**  * 一個產生字母對象的 享元工廠(單例工廠)  */ public class LetterFactory {  private Map<String, Letter> map;  private static LetterFactory instance = new LetterFactory();    private LetterFactory() {   map = new HashMap<String, Letter>();  }    public static LetterFactory getInstance() {   return instance;  }    public void add(Letter letter) {   if (letter != null && !map.containsKey(letter.getName())) {    map.put(letter.getName(), letter);   }   System.out.println("map.size====" + map.size());  }    public Letter get(String name) {   return map.get(name);  }   } 
public class Test {  public static void main(String[] args) {   LetterFactory factory = LetterFactory.getInstance();   String word = "easiness";   addLetterByName(factory, word);      getLetter(factory, word);  }  //添加字母對象  static void addLetterByName(LetterFactory factory, String word) {   for (char c : word.toCharArray()) {    factory.add(new Letter(c + ""));   }  }  //輸出字母對象  static void getLetter(LetterFactory factory, String word) {   for (char c : word.toCharArray()) {    System.out.println(factory.get(c + ""));   }  } } 


列印:

map.size====1 map.size====2 map.size====2 map.size====3 map.size====4 map.size====5 map.size====5 flyweight.Letter@3343c8b3 flyweight.Letter@272d7a10 flyweight.Letter@3343c8b3 flyweight.Letter@1aa8c488 flyweight.Letter@3dfeca64 flyweight.Letter@22998b08 flyweight.Letter@1aa8c488 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.