1. 程式人生 > >設計模式之(十一)享元模式Flyweight

設計模式之(十一)享元模式Flyweight

Flyweight模式定義:
避免大量擁有相同內容的小類的開銷(如耗費記憶體),使大家共享一個類(元類).

為什麼使用?
面嚮物件語言的原則就是一切都是物件,但是如果真正使用起來,有時物件數可能顯得很龐大,比如,字處理軟體,如果以每個文字都作為一個物件,幾千個字,物件數就是幾千,無疑耗費記憶體,那麼我們還是要"求同存異",找出這些物件群的共同點,設計一個元類,封裝可以被共享的類,另外,還有一些特性是取決於應用(context),是不可共享的,這也Flyweight中兩個重要概念內部狀態intrinsic和外部狀態extrinsic之分.

說白點,就是先捏一個的原始模型,然後隨著不同場合和環境,再產生各具特徵的具體模型,很顯然,在這裡需要產生不同的新物件,所以Flyweight模式中常出現Factory模式.Flyweight的內部狀態是用來共享的,Flyweight factory負責維護一個Flyweight pool(模式池)來存放內部狀態的物件.

Flyweight模式是一個提高程式效率和效能的模式,會大大加快程式的執行速度.應用場合很多:比如你要從一個數據庫中讀取一系列字串,這些字串中有許多是重複的,那麼我們可以將這些字串儲存在Flyweight池(pool)中.

如何使用?

我們先從Flyweight抽象介面開始:

public interface Flyweight 
{
  public void operation( ExtrinsicState state );
}

//用於本模式的抽象資料型別(自行設計)
public interface ExtrinsicState { }

下面是介面的具體實現(ConcreteFlyweight) ,併為內部狀態增加記憶體空間, ConcreteFlyweight必須是可共享的,它儲存的任何狀態都必須是內部(intrinsic),也就是說,ConcreteFlyweight必須和它的應用環境場合無關.

public class ConcreteFlyweight implements Flyweight {
  private IntrinsicState state; 
  
  public void operation( ExtrinsicState state ) 
  { 
      //具體操作
  }

}

當然,並不是所有的Flyweight具體實現子類都需要被共享的,所以還有另外一種不共享的ConcreteFlyweight:

public class UnsharedConcreteFlyweight implements Flyweight {

  public void operation( ExtrinsicState state ) { }

}

Flyweight factory負責維護一個Flyweight池(存放內部狀態),當客戶端請求一個共享Flyweight時,這個factory首先搜尋池中是否已經有可適用的,如果有,factory只是簡單返回送出這個物件,否則,建立一個新的物件,加入到池中,再返回送出這個物件.池

public class FlyweightFactory { 
  //Flyweight pool
  private Hashtable flyweights = new Hashtable(); 

  public Flyweight getFlyweight( Object key ) { 

    Flyweight flyweight = (Flyweight) flyweights.get(key); 

    if( flyweight == null ) {
      //產生新的ConcreteFlyweight
      flyweight = new ConcreteFlyweight(); 
      flyweights.put( key, flyweight ); 
    } 

    return flyweight; 
  } 
}

至此,Flyweight模式的基本框架已經就緒,我們看看如何呼叫:

FlyweightFactory factory = new FlyweightFactory(); 
Flyweight fly1 = factory.getFlyweight( "Fred" ); 
Flyweight fly2 = factory.getFlyweight( "Wilma" );
......

從呼叫上看,好象是個純粹的Factory使用,但奧妙就在於Factory的內部設計上.

Flyweight模式在XML等資料來源中應用
我們上面已經提到,當大量從資料來源中讀取字串,其中肯定有重複的,那麼我們使用Flyweight模式可以提高效率,以唱片CD為例,在一個XML檔案中,存放了多個CD的資料.

每個CD有三個欄位:
1.出片日期(year)
2.歌唱者姓名等資訊(artist)
3.唱片曲目 (title)

其中,歌唱者姓名有可能重複,也就是說,可能有同一個演唱者的多個不同時期 不同曲目的CD.我們將"歌唱者姓名"作為可共享的ConcreteFlyweight.其他兩個欄位作為UnsharedConcreteFlyweight.

首先看看資料來源XML檔案的內容:


<?xml version="1.0"?>
<collection>

<cd>
<title>Another Green World</title>
<year>1978</year>
<artist>Eno, Brian</artist>
</cd>

<cd>
<title>Greatest Hits</title>
<year>1950</year>
<artist>Holiday, Billie</artist>
</cd>

<cd>
<title>Taking Tiger Mountain (by strategy)</title>
<year>1977</year>
<artist>Eno, Brian</artist>
</cd>

.......

</collection>


雖然上面舉例CD只有3張,CD可看成是大量重複的小類,因為其中成分只有三個欄位,而且有重複的(歌唱者姓名).

CD就是類似上面介面 Flyweight:


public class CD {

  private String title;
  private int year;
  private Artist artist;

  public String getTitle() {  return title; }
  public int getYear() {    return year;  }
  public Artist getArtist() {    return artist;  }

  public void setTitle(String t){    title = t;}
  public void setYear(int y){year = y;}
  public void setArtist(Artist a){artist = a;}

}

將"歌唱者姓名"作為可共享的ConcreteFlyweight:

public class Artist {

  //內部狀態
  private String name;

  // note that Artist is immutable.
  String getName(){return name;}

  Artist(String n){
    name = n;
  } 

}

再看看Flyweight factory,專門用來製造上面的可共享的ConcreteFlyweight:Artist

public class ArtistFactory {

  Hashtable pool = new Hashtable();

  Artist getArtist(String key){

    Artist result;
    result = (Artist)pool.get(key);
    ////產生新的Artist
    if(result == null) {
      result = new Artist(key);
      pool.put(key,result);
      
    }
    return result;
  }

}

當你有幾千張甚至更多CD時,Flyweight模式將節省更多空間,共享的flyweight越多,空間節省也就越大.

相關推薦

C#設計模式模式Flyweight Pattern)【結構型】

eal 客戶 來看 滿足 對象狀態 英文 輔助 3.3 fig 原文:C#設計模式之十一享元模式(Flyweight Pattern)【結構型】一、引言 今天我們要講【結構型】設計模式的第六個模式,該模式是【享元模式】,英文名稱是:Flyweight Pattern。還

設計模式()模式Flyweight

Flyweight模式定義: 避免大量擁有相同內容的小類的開銷(如耗費記憶體),使大家共享一個類(元類). 為什麼使用? 面嚮物件語言的原則就是一切都是物件,但是如果真正使用起來,有時物件數可能顯得很龐大,比如,字處理軟體,如果以每個文字都作為一個物件,幾千個字,物件數就

Java進階篇設計模式 ---- 策略模式和模板方法模式

前言 在上一篇中我們學習了行為型模式的訪問者模式(Visitor Pattern)和中介者模式(Mediator Pattern)。本篇則來學習下行為型模式的兩個模式,策略模式(Strategy Pattern)和模板模式(Mediator Pattern)。 策略模式 簡介 策略模式(Stra

Java經典設計模式種行為型模式(附例項和詳解)

Java經典設計模式共有21中,分為三大類:建立型模式(5種)、結構型模式(7種)和行為型模式(11種)。 行為型模式細分為如下11種:策略模式、模板方法模式、觀察者模式、迭代子模式、責任鏈模式、命令模式、備忘錄模式、狀態模式、訪問者模式、中介者模式、直譯

Java設計模式 ---- 策略模式和模板方法模式

得到 ref images 幾種算法 www. lse -type 中介者模式 vat 前言 在上一篇中我們學習了行為型模式的訪問者模式(Visitor Pattern)和中介者模式(Mediator Pattern)。本篇則來學習下行為型模式的兩個模式,策略模式(Stra

設計模式)——生成器模式

所有 boolean concrete @override ttr stat bsp println 無需 1.描述 將一組復雜對象的構建與他的表示相分離,使同樣的構建過程可以創建不同的表示。 2.模式的使用 ·產品(Product):具體生成器要構造的復雜對象。 ·抽象生

C#設計模式七中介者模式(Mediator Pattern)【行為型】

[] 過多 深入 理解 申請 代碼實現 控制 name 缺點 原文:C#設計模式之十七中介者模式(Mediator Pattern)【行為型】一、引言 今天我們開始講“行為型”設計模式的第五個模式,該模式是【中介者模式】,英文名稱是:Mediator Pattern。還

C#設計模式六觀察者模式(Observer Pattern)【行為型】

ngx 現實生活 松耦合 mon html 機制 account current 很好 原文:C#設計模式之十六觀察者模式(Observer Pattern)【行為型】一、引言 今天是2017年11月份的最後一天,也就是2017年11月30日,利用今天再寫一個模式,爭取

設計模式(11)模式

tree 們的 http 模式 sign 提高 所有 lin github 模式介紹 享元模式用於創建許多小的、相關的對象,而無需為此調用大量開銷工作,從而提高性能和可維護性。 享元模式允許對象的許多實例共享它們的內在狀態,從而減少與創建它們相關的成本。 示例 我們以Sli

設計模式 (二)直譯器模式

直譯器模式 直譯器模式的場景就是一個計算器,計算簡單的+,-運算,a+b-c, a-b+c這種,給出a,b,c的值,計算表示式結果。需要設計一個表示式分析。 直譯器是一種按照規定語法進行解析的方案,在現在專案中使用極少。 直譯器模式的優點 擴充套件性較好

設計模式)代理模式Proxy(結構型)

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

C#設計模式(13)——模式

1.享元模式介紹   在軟體開發中我們經常遇到多次使用相似或者相同物件的情況,如果每次使用這個物件都去new一個新的例項會很浪費資源。這時候很多人會想到前邊介紹過的一個設計模式:原型模式,原型模式通過拷貝現有物件來生成一個新的例項,使用拷貝來替代new。原型模式可以很好的解決建立多個相同/相似例項的問題,為

大資料專案實戰:11.工廠模式講解以及DAOFactory開發

如果沒有工廠模式,可能會出現的問題: ITaskDAO介面和TaskDAOImpl實現類;實現類是可能會更換的;那麼,如果你就使用普通的方式來建立DAO,比如ITaskDAO taskDAO = new TaskDAOImpl(),那麼後續,如果你的TaskDAO的實現類變更了,那麼你就必須在你

設計模式)—— 狀態模式

一、含義 允許物件在內部狀態改變時改變它的行為,物件看起來好像修改了它的類。也就是說當一個物件有許多狀態的時候,我們可以把每個物件抽離出來作為一個具體的類。 二、要點 1.狀態模式允許一個物件基於內部狀態而擁有不同的行為。 2.通過將每個狀態封裝進一個類,我們把以後需要做的任何改變區

設計模式》學習筆記——模式

享元模式(Flyweight Pattern)是一種軟體設計模式。  它使用共享物件,用來儘可能減少記憶體使用量以及分享資訊給儘可能多的相似物件;適合用於當大量物件只是重複因而導致無法令人接受的使用大

大話設計模式)工廠模式

(大話設計模式) 最近在研究大話設計模式,正好終結一下,以備自己後續檢視。 書中對設計模式分類有28種,今天終結下最為常見的模式,工廠模式。工廠模式有三種:簡單工廠模式,工廠方法模式,抽象工廠模式。 下面說說這三種模式的差異,並一一舉以書中的例子加以說明。 簡單工廠模式:用一個單獨的類來做建

設計模式學習筆記】模式

享元模式:主要用於減少建立物件的數量,以減少記憶體佔用和提高效能。這種型別的設計模式屬於結構型模式,它提供了減少物件數量從而改善應用所需的物件結構的方式。【菜鳥】 文章目錄 1.1 寶馬車長這樣 1.2 工廠是這樣塗裝的

設計模式(11)-模式

簡介 為什麼要使用享元模式 在系統中,有時會出現多個物件完全相同或者非常相似的情況,如果這些相似的物件過多,那麼在系統執行時,將會浪費很多的資源,導致執行代價過高,效能下降等問題。享元模式就是為了解決這一問題而出現的。享元模式運用共享技術實現相同或相似物件的

設計模式的征途—12.Flyweight模式

現在在大力推行節約型社會,“浪費可恥,節儉光榮”。在軟體系統中,有時候也會存在資源浪費的情況,例如,在計算機記憶體中儲存了多個完全相同或者非常相似的物件,如果這些物件的數量太多將導致系統執行代價過高。那麼,是否存在一種技術可以用於節約記憶體使用空間,實現對這些相同或者相似物件的共享訪問呢?答案是肯定的,這種技

Java設計模式)訪問者模式 中介者模式

(二十一)訪問者模式 對已存在的類進行擴充套件,通常需要增加方法,但是如果需要的行為與現有的物件模型不一致,或者無法修改現有程式碼。在這種情況下,不更改類的層次結構,就無法擴充套件該層次結構的行為。如果運用了訪問者模式,就可以支援開發人員擴充套件該類層次結構的行為。 和直譯