程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Java設計模式研究之Flyweight模式

Java設計模式研究之Flyweight模式

編輯:關於JAVA

GOF:運用共享技術有效地支持大量細粒度的對象。

解釋一下概念:也就是說在一個系統中如果有多個相同的對象,那麼只共享一份就可以了,不必每個都去實例化一個對象。比如說(這裡引用GOF書中的例子)一個文本系統,每個字母定一個對象,那麼大小寫字母一共就是52個,那麼就要定義52個對象。如果有一個1M的文本,那麼字母是何其的多,如果每個字母都定義一個對象那麼內存早就爆了。那麼如果要是每個字母都共享一個對象,那麼就大大節約了資源。

在Flyweight模式中,由於要產生各種各樣的對象,所以在Flyweight(享元)模式中常出現Factory模式。Flyweight的內部狀態是用來共享的,Flyweight factory負責維護一個對象存儲池(Flyweight Pool)來存放內部狀態的對象。Flyweight模式是一個提高程序效率和性能的模式,會大大加快程序的運行速度.應用場合很多,下面舉個例子:

先定義一個抽象的Flyweight類:

package Flyweight;
public abstract class Flyweight
...
{
  public abstract void operation();
}//end abstract class Flyweight

在實現一個具體類:

package Flyweight;
public class ConcreteFlyweight extends Flyweight
...
{
  private String string;
  public ConcreteFlyweight(String str)
  ...
  {
   string = str;
  }//end ConcreteFlyweight(...)
  public void operation()
  ...
  {
   System.out.println("Concrete---Flyweight : " + string);
  }//end operation()
}//end class ConcreteFlyweight

實現一個工廠方法類:

package Flyweight;
import java.util.Hashtable;
public class FlyweightFactory
...
{
  private Hashtable flyweights = new Hashtable();//----------------------------1
  public FlyweightFactory() ...{}
  public Flyweight getFlyWeight(Object obj)
  ...
  {
   Flyweight flyweight = (Flyweight) flyweights.get(obj);//----------------2
   if(flyweight == null) ...{//---------------------------------------------------3
    //產生新的ConcreteFlyweight
    flyweight = new ConcreteFlyweight((String)obj);
    flyweights.put(obj, flyweight);//--------------------------------------5
   }
   return flyweight;//---------------------------------------------------------6
  }//end GetFlyWeight(...)
  public int getFlyweightSize()
  ...
  {
   return flyweights.size();
  }
}//end class FlyweightFactory

這個工廠方法類非常關鍵,這裡詳細解釋一下:

在1處定義了一個Hashtable用來存儲各個對象;在2處選出要實例化的對象,在6處將該對象返回,如果在Hashtable中沒有要選擇的對象,此時變量flyweight為null,產生一個新的flyweight存儲在Hashtable中,並將該對象返回。

最後看看Flyweight的調用:

package Flyweight;
import java.util.Hashtable;
public class FlyweightPattern ...{
  FlyweightFactory factory = new FlyweightFactory();
  Flyweight fly1;
  Flyweight fly2;
  Flyweight fly3;
  Flyweight fly4;
  Flyweight fly5;
  Flyweight fly6;
  /** *//** Creates a new instance of FlyweightPattern */
  public FlyweightPattern() ...{
   fly1 = factory.getFlyWeight("Google");
   fly2 = factory.getFlyWeight("Qutr");
   fly3 = factory.getFlyWeight("Google");
   fly4 = factory.getFlyWeight("Google");
   fly5 = factory.getFlyWeight("Google");
   fly6 = factory.getFlyWeight("Google");
  }//end FlyweightPattern()
  public void showFlyweight()
  ...
  {
   fly1.operation();
   fly2.operation();
   fly3.operation();
   fly4.operation();
   fly5.operation();
   fly6.operation();
   int objSize = factory.getFlyweightSize();
   System.out.println("objSize = " + objSize);
  }//end showFlyweight()
  public static void main(String[] args)
  ...
  {
   System.out.println("The FlyWeight Pattern!");
   FlyweightPattern fp = new FlyweightPattern();
   fp.showFlyweight();
  }//end main(...)
}//end class FlyweightPattern

下面是運行結果:

Concrete---Flyweight : Google
Concrete---Flyweight : Qutr
Concrete---Flyweight : Google
Concrete---Flyweight : Google
Concrete---Flyweight : Google
Concrete---Flyweight : Google
objSize = 2

我們定義了6個對象,其中有5個是相同的,按照Flyweight模式的定義“Google”應該共享一個對象,在實際的對象數中我們可以看出實際的對象卻是只有2個。

下面給出一個簡易的UML圖:

總結:

Flyweight(享元)模式是如此的重要,因為它能幫你在一個復雜的系統中大量的節省內存空間。在GOF的書中舉了文本處理的例子,我覺得非常恰當。那麼,在Java中String這個類型比較特殊,為什麼呢,看下面的例子:

String a = "hello";
String b = "hello";
if(a == b)
  System.out.println("OK");
else
  System.out.println("Error");

輸出結果是:OK。稍有經驗的人都可以看出if條件比較的是兩a和b的地址,也可以說是內存空間。那麼Sting的實現是不是使用了Flyweight模式呢,不得而知,到現在還沒有研究過。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved