亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > Java > 正文

23種設計模式(21)java享元模式

2024-07-13 10:17:24
字體:
來源:轉載
供稿:網友

在閻宏博士的《JAVA與模式》一書中開頭是這樣描述享元(Flyweight)模式的:

Flyweight在拳擊比賽中指最輕量級,即“蠅量級”或“雨量級”,這里選擇使用“享元模式”的意譯,是因為這樣更能反映模式的用意。享元模式是對象的結構模式。享元模式以共享的方式高效地支持大量的細粒度對象。

Java中的String類型

  在JAVA語言中,String類型就是使用了享元模式。String對象是final類型,對象一旦創建就不可改變。在JAVA中字符串常量都是存在常量池中的,JAVA會確保一個字符串常量在常量池中只有一個拷貝。String a="abc",其中"abc"就是一個字符串常量。

public class Test { public static void main(String[] args) {  String a = "abc";  String b = "abc";  System.out.println(a==b); }}

上面的例子中結果為:true ,這就說明a和b兩個引用都指向了常量池中的同一個字符串常量"abc"。這樣的設計避免了在創建N多相同對象時所產生的不必要的大量的資源消耗。

享元模式的結構

  享元模式采用一個共享來避免大量擁有相同內容對象的開銷。這種開銷最常見、最直觀的就是內存的損耗。享元對象能做到共享的關鍵是區分內蘊狀態(Internal State)外蘊狀態(External State)

       一個內蘊狀態是存儲在享元對象內部的,并且是不會隨環境的改變而有所不同。因此,一個享元可以具有內蘊狀態并可以共享。

    一個外蘊狀態是隨環境的改變而改變的、不可以共享的。享元對象的外蘊狀態必須由客戶端保存,并在享元對象被創建之后,在需要使用的時候再傳入到享元對象內部。外蘊狀態不可以影響享元對象的內蘊狀態,它們是相互獨立的。

  享元模式可以分成單純享元模式和復合享元模式兩種形式。

單純享元模式  

  在單純的享元模式中,所有的享元對象都是可以共享的。

java,享元模式

單純享元模式所涉及到的角色如下:

抽象享元(Flyweight)角色:給出一個抽象接口,以規定出所有具體享元角色需要實現的方法。
具體享元(ConcreteFlyweight)角色:實現抽象享元角色所規定出的接口。如果有內蘊狀態的話,必須負責為內蘊狀態提供存儲空間。
享元工廠(FlyweightFactory)角色:本角色負責創建和管理享元角色。本角色必須保證享元對象可以被系統適當地共享。當一個客戶端對象調用一個享元對象的時候,享元工廠角色會檢查系統中是否已經有一個符合要求的享元對象。如果已經有了,享元工廠角色就應當提供這個已有的享元對象;如果系統中沒有一個適當的享元對象的話,享元工廠角色就應當創建一個合適的享元對象。

源代碼

抽象享元角色類

public interface Flyweight { //一個示意性方法,參數state是外蘊狀態 public void operation(String state);}

具體享元角色類ConcreteFlyweight有一個內蘊狀態,在本例中一個Character類型的intrinsicState屬性代表,它的值應當在享元對象被創建時賦予。所有的內蘊狀態在對象創建之后,就不會再改變了。

如果一個享元對象有外蘊狀態的話,所有的外部狀態都必須存儲在客戶端,在使用享元對象時,再由客戶端傳入享元對象。這里只有一個外蘊狀態,operation()方法的參數state就是由外部傳入的外蘊狀態。

public class ConcreteFlyweight implements Flyweight { private Character intrinsicState = null; /** * 構造函數,內蘊狀態作為參數傳入 * @param state */ public ConcreteFlyweight(Character state){  this.intrinsicState = state; }  /** * 外蘊狀態作為參數傳入方法中,改變方法的行為, * 但是并不改變對象的內蘊狀態。 */ @Override public void operation(String state) {  // TODO Auto-generated method stub  System.out.println("Intrinsic State = " + this.intrinsicState);  System.out.println("Extrinsic State = " + state); }}

享元工廠角色類,必須指出的是,客戶端不可以直接將具體享元類實例化,而必須通過一個工廠對象,利用一個factory()方法得到享元對象。一般而言,享元工廠對象在整個系統中只有一個,因此也可以使用單例模式。

當客戶端需要單純享元對象的時候,需要調用享元工廠的factory()方法,并傳入所需的單純享元對象的內蘊狀態,由工廠方法產生所需要的享元對象。

public class FlyweightFactory { private Map<Character,Flyweight> files = new HashMap<Character,Flyweight>();  public Flyweight factory(Character state){  //先從緩存中查找對象  Flyweight fly = files.get(state);  if(fly == null){   //如果對象不存在則創建一個新的Flyweight對象   fly = new ConcreteFlyweight(state);   //把這個新的Flyweight對象添加到緩存中   files.put(state, fly);  }  return fly; }}

客戶端類

public class Client { public static void main(String[] args) {  // TODO Auto-generated method stub  FlyweightFactory factory = new FlyweightFactory();  Flyweight fly = factory.factory(new Character('a'));  fly.operation("First Call");    fly = factory.factory(new Character('b'));  fly.operation("Second Call");    fly = factory.factory(new Character('a'));  fly.operation("Third Call"); }}

雖然客戶端申請了三個享元對象,但是實際創建的享元對象只有兩個,這就是共享的含義。運行結果如下:

java,享元模式

復合享元模式

  在單純享元模式中,所有的享元對象都是單純享元對象,也就是說都是可以直接共享的。還有一種較為復雜的情況,將一些單純享元使用合成模式加以復合,形成復合享元對象。這樣的復合享元對象本身不能共享,但是它們可以分解成單純享元對象,而后者則可以共享。

java,享元模式

復合享元角色所涉及到的角色如下:

抽象享元(Flyweight)角色:給出一個抽象接口,以規定出所有具體享元角色需要實現的方法。

具體享元(ConcreteFlyweight)角色:實現抽象享元角色所規定出的接口。如果有內蘊狀態的話,必須負責為內蘊狀態提供存儲空間。

復合享元(ConcreteCompositeFlyweight)角色:復合享元角色所代表的對象是不可以共享的,但是一個復合享元對象可以分解成為多個本身是單純享元對象的組合。復合享元角色又稱作不可共享的享元對象。

享元工廠(FlyweightFactory)角色:本角 色負責創建和管理享元角色。本角色必須保證享元對象可以被系統適當地共享。當一個客戶端對象調用一個享元對象的時候,享元工廠角色會檢查系統中是否已經有 一個符合要求的享元對象。如果已經有了,享元工廠角色就應當提供這個已有的享元對象;如果系統中沒有一個適當的享元對象的話,享元工廠角色就應當創建一個 合適的享元對象。

源代碼

抽象享元角色類

public interface Flyweight { //一個示意性方法,參數state是外蘊狀態 public void operation(String state);}

具體享元角色類

public class ConcreteFlyweight implements Flyweight { private Character intrinsicState = null; /** * 構造函數,內蘊狀態作為參數傳入 * @param state */ public ConcreteFlyweight(Character state){  this.intrinsicState = state; }  /** * 外蘊狀態作為參數傳入方法中,改變方法的行為, * 但是并不改變對象的內蘊狀態。 */ @Override public void operation(String state) {  // TODO Auto-generated method stub  System.out.println("Intrinsic State = " + this.intrinsicState);  System.out.println("Extrinsic State = " + state); }}

復合享元對象是由單純享元對象通過復合而成的,因此它提供了add()這樣的聚集管理方法。由于一個復合享元對象具有不同的聚集元素,這些聚集元素在復合享元對象被創建之后加入,這本身就意味著復合享元對象的狀態是會改變的,因此復合享元對象是不能共享的。

復合享元角色實現了抽象享元角色所規定的接口,也就是operation()方法,這個方法有一個參數,代表復合享元對象的外蘊狀態。一個復合享元對象的所有單純享元對象元素的外蘊狀態都是與復合享元對象的外蘊狀態相等的;而一個復合享元對象所含有的單純享元對象的內蘊狀態一般是不相等的,不然就沒有使用價值了。

public class ConcreteCompositeFlyweight implements Flyweight {  private Map<Character,Flyweight> files = new HashMap<Character,Flyweight>(); /** * 增加一個新的單純享元對象到聚集中 */ public void add(Character key , Flyweight fly){  files.put(key,fly); } /** * 外蘊狀態作為參數傳入到方法中 */ @Override public void operation(String state) {  Flyweight fly = null;  for(Object o : files.keySet()){   fly = files.get(o);   fly.operation(state);  }  }}

享元工廠角色提供兩種不同的方法,一種用于提供單純享元對象,另一種用于提供復合享元對象。

public class FlyweightFactory { private Map<Character,Flyweight> files = new HashMap<Character,Flyweight>(); /** * 復合享元工廠方法 */ public Flyweight factory(List<Character> compositeState){  ConcreteCompositeFlyweight compositeFly = new ConcreteCompositeFlyweight();    for(Character state : compositeState){   compositeFly.add(state,this.factory(state));  }    return compositeFly; } /** * 單純享元工廠方法 */ public Flyweight factory(Character state){  //先從緩存中查找對象  Flyweight fly = files.get(state);  if(fly == null){   //如果對象不存在則創建一個新的Flyweight對象   fly = new ConcreteFlyweight(state);   //把這個新的Flyweight對象添加到緩存中   files.put(state, fly);  }  return fly; }}

客戶端角色

public class Client { public static void main(String[] args) {  List<Character> compositeState = new ArrayList<Character>();  compositeState.add('a');  compositeState.add('b');  compositeState.add('c');  compositeState.add('a');  compositeState.add('b');    FlyweightFactory flyFactory = new FlyweightFactory();  Flyweight compositeFly1 = flyFactory.factory(compositeState);  Flyweight compositeFly2 = flyFactory.factory(compositeState);  compositeFly1.operation("Composite Call");    System.out.println("---------------------------------");    System.out.println("復合享元模式是否可以共享對象:" + (compositeFly1 == compositeFly2));    Character state = 'a';  Flyweight fly1 = flyFactory.factory(state);  Flyweight fly2 = flyFactory.factory(state);  System.out.println("單純享元模式是否可以共享對象:" + (fly1 == fly2)); }}

運行結果如下:

java,享元模式

從運行結果可以看出,一個復合享元對象的所有單純享元對象元素的外蘊狀態都是與復合享元對象的外蘊狀態相等的。即外運狀態都等于Composite Call。
從運行結果可以看出,一個復合享元對象所含有的單純享元對象的內蘊狀態一般是不相等的。即內蘊狀態分別為b、c、a。
從運行結果可以看出,復合享元對象是不能共享的。即使用相同的對象compositeState通過工廠分別兩次創建出的對象不是同一個對象。
從運行結果可以看出,單純享元對象是可以共享的。即使用相同的對象state通過工廠分別兩次創建出的對象是同一個對象。

享元模式的優缺點

        享元模式的優點在于它大幅度地降低內存中對象的數量。但是,它做到這一點所付出的代價也是很高的:

享元模式使得系統更加復雜。為了使對象可以共享,需要將一些狀態外部化,這使得程序的邏輯復雜化。
享元模式將享元對象的狀態外部化,而讀取外部狀態使得運行時間稍微變長。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。


注:相關教程知識閱讀請移步到JAVA教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
96国产粉嫩美女| 高清欧美性猛交xxxx| 国产欧美精品久久久| 中文字幕日韩免费视频| 久久亚洲私人国产精品va| 91产国在线观看动作片喷水| 欧美一级bbbbb性bbbb喷潮片| 欧美俄罗斯性视频| 日产日韩在线亚洲欧美| 成人妇女淫片aaaa视频| 高跟丝袜欧美一区| 欧美午夜激情在线| 欧美日韩亚洲系列| 综合网日日天干夜夜久久| 久久精品国产综合| 国产一区二区三区日韩欧美| 日韩精品在线视频| 久久国产精品久久久久| 国产精品偷伦一区二区| 国产精品女人久久久久久| 欧美专区第一页| 91精品视频在线| 亚洲国产成人爱av在线播放| 亚洲缚视频在线观看| 国产中文日韩欧美| 精品国产福利在线| 国产精品免费网站| 日韩欧美国产视频| 中文字幕精品国产| 美女视频黄免费的亚洲男人天堂| 亚洲男人的天堂在线| 夜夜嗨av色综合久久久综合网| 欧美最猛黑人xxxx黑人猛叫黄| 97超视频免费观看| 亚洲精品在线观看www| 一区二区三区视频免费| 日韩精品视频在线免费观看| 日韩av最新在线观看| 激情亚洲一区二区三区四区| 国产香蕉97碰碰久久人人| 欧美黑人极品猛少妇色xxxxx| 精品亚洲aⅴ在线观看| 日韩免费观看网站| 久久久av亚洲男天堂| 亚洲精品综合久久中文字幕| 欧美一性一乱一交一视频| 97在线视频精品| 久久久久免费精品国产| 欧美日韩亚洲一区二区三区| 日韩免费高清在线观看| 97久久久免费福利网址| 亚洲成人av在线播放| 国产高清视频一区三区| 精品人伦一区二区三区蜜桃网站| 欧美成人全部免费| 亚洲最大激情中文字幕| 久色乳综合思思在线视频| 伊人青青综合网站| 国产精品美女网站| 欧美理论电影在线播放| 欧美美女操人视频| 欧美性猛交xxxx免费看漫画| 亚洲午夜久久久影院| 欧美国产在线视频| 欧美超级免费视 在线| 亚洲成色777777在线观看影院| 亚洲性av网站| 北条麻妃一区二区三区中文字幕| 久久久久久久久亚洲| 97视频在线免费观看| 日韩**中文字幕毛片| 一区二区三区精品99久久| 黄色成人av网| 懂色aⅴ精品一区二区三区蜜月| 日韩欧美亚洲一二三区| 久久男人av资源网站| 国产精品www| 国产成人精彩在线视频九色| 午夜精品在线观看| 久久精品一偷一偷国产| 亚洲精品久久久一区二区三区| 久久精品国产亚洲| 国产精品自产拍在线观看中文| 亚洲开心激情网| 97视频在线观看播放| 97久久精品人人澡人人爽缅北| 国产精品人成电影在线观看| 亚洲精品小视频| 久久伊人精品天天| 亚洲丝袜在线视频| 青青草99啪国产免费| 国产原创欧美精品| 日韩av电影在线播放| 日韩精品欧美激情| 在线丨暗呦小u女国产精品| 色中色综合影院手机版在线观看| 久久精品夜夜夜夜夜久久| zzijzzij亚洲日本成熟少妇| 国内成人精品视频| 成人在线免费观看视视频| 国产精品普通话| 国产视频久久久久| 国产一区二区丝袜高跟鞋图片| 国产精品日韩在线一区| 在线国产精品播放| 欧美在线视频免费播放| 亚洲成人黄色在线观看| 国产精品美女免费| 欧美精品18videos性欧| 国产精品18久久久久久首页狼| 欧美亚洲国产视频小说| 欧美色视频日本高清在线观看| 日韩欧美中文字幕在线播放| 91高清免费在线观看| 欧美在线播放视频| 日韩精品视频在线观看网址| 国产精品久久久久久影视| 亚洲影院污污.| 久久视频在线播放| 91精品久久久久久久久中文字幕| 中文字幕亚洲欧美日韩2019| 日韩成人在线网站| 欧美精品成人91久久久久久久| 欧美大荫蒂xxx| 国产精品青青在线观看爽香蕉| 狠狠做深爱婷婷久久综合一区| 爱福利视频一区| 欧美日韩亚洲视频一区| 91欧美日韩一区| 91成人国产在线观看| 久久69精品久久久久久久电影好| 国产日韩欧美在线播放| 成人观看高清在线观看免费| 欧美黑人国产人伦爽爽爽| 欧美老妇交乱视频| 久久久91精品国产一区不卡| 成人亚洲欧美一区二区三区| 91av免费观看91av精品在线| 日韩欧美在线播放| 国产精品激情自拍| 日韩欧美亚洲国产一区| 日韩视频免费在线观看| 日韩亚洲国产中文字幕| 久久免费视频在线观看| 日韩久久免费视频| 中文字幕精品一区二区精品| 深夜福利一区二区| 欧美夫妻性生活视频| 日韩精品免费综合视频在线播放| 韩剧1988在线观看免费完整版| 日本久久久久亚洲中字幕| 亚洲最大中文字幕| 久久福利网址导航| 国产亚洲精品美女久久久久| 日韩在线视频免费观看高清中文| 亚洲精品久久久久| 国内精品视频在线| 色无极影院亚洲| 亚洲第一区中文字幕| 久久97精品久久久久久久不卡| 国产精品欧美一区二区| 国产精品白嫩美女在线观看| 亚洲成色999久久网站| 欧美成人午夜视频|