国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

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

2019-11-26 14:25:04
字體:
來源:轉載
供稿:網友

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

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

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

2016427120136286.png (580×276)

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

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

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

2016427120204633.png (600×263)

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

/**  * 字母  */ 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 

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 垦利县| 桃园市| 五指山市| 东阳市| 沅江市| 乐陵市| 镇宁| 永川市| 伊金霍洛旗| 蓬溪县| 垦利县| 阳西县| 海南省| 南郑县| 西和县| 加查县| 上饶市| 涞源县| 仁怀市| 竹溪县| 云阳县| 监利县| 怀化市| 共和县| 石台县| 清远市| 武汉市| 佛教| 日土县| 乡城县| 德钦县| 轮台县| 阿勒泰市| 保定市| 甘德县| 大石桥市| 军事| 乌什县| 浑源县| 乌兰察布市| 云南省|