`

設計模式之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)

    享元模式(Flyweight Pattern)是一种结构型设计模式,用于减少创建大量小对象所带来的内存开销。通过共享对象,享元模式能够有效地支持大量细粒度的对象,减少内存使用并提高性能。它常用于需要大量重复对象的场景...

    C#设计模式之Flyweight

    "Flyweight"(享元)设计模式是一种结构型模式,其核心目的是为了有效地支持大量细粒度对象的创建和使用,通过共享已经存在的对象来减少内存消耗,提高系统性能。在C#中,Flyweight模式尤其适用于那些内部状态可共享...

    学习php设计模式 php实现享元模式(flyweight)

    享元模式(Flyweight Pattern)是软件设计中的一种结构型设计模式,它通过共享技术来支持大量细粒度的对象,以此来降低内存中对象的数量。在PHP中实现享元模式,可以帮助我们优化程序性能,特别是在对象数目过多时,...

    设计模式(C#)之享元模式(Flyweight Pattern)

    享元模式是设计模式中的一种结构型模式,它主要通过共享已有对象来减少内存中对象的数量,从而提高系统性能。在C#编程中,享元模式尤其适用于那些创建大量相似对象且内存消耗较大的场景。本篇文章将深入探讨享元模式...

    设计模式学习笔记--Flyweight享元模式.docx

    享元模式是一种设计模式,属于构造型模式,其主要目的是减少对象的数量,通过共享大量相似对象的内部状态来节省内存。这种模式在处理大量细粒度对象时特别有用,能够有效地提高系统的性能。 享元模式的核心是...

    设计模式之轻量级Flyweight

    本文将深入探讨“轻量级”设计模式之一——Flyweight(享元)模式,它是如何在减少内存消耗的同时提高系统性能的。 Flyweight模式的核心思想是共享对象,通过复用大量相似对象来减少内存占用。这种模式通常在处理...

    C#面向对象设计模式纵横谈(12):Flyweight 享元模式(结构型模式) (Level 300)

    在这个“C#面向对象设计模式纵横谈(12)”中,我们将深入探讨享元模式的概念、实现方式以及如何在实际项目中应用。 享元模式的核心思想是区分对象的状态和行为。状态分为内部状态和外部状态,其中内部状态是对象共有...

    C++设计模式之享元模式(Flyweight)

    C++设计模式之享元模式(Flyweight) C++设计模式之享元模式(Flyweight)是一种结构型设计模式,主要用于解决大量相似对象的创建和操作所带来的内存负载问题。该模式的主要设计目标是通过共享对象来减少内存负载,...

    享元模式flyweight

    享元模式(Flyweight Pattern)是一种结构型设计模式,它能有效地减少系统中对象的数量,从而降低内存消耗,提高性能。这种模式通过共享大量相似对象的内部状态来达到这一目标,而只保留对象的外部状态在外部管理。...

    C#面向对象设计模式纵横谈\12 结构型模式Flyweight享元模式.zip

    在这里与各位分享本人从网络上下载的C#面向对象设计模式纵横谈系列视频,共有25节,除了第一节需要各位贡献一点资源分以作为对本人上传资源的回馈,后面的其他资源均不需要... 这是第12节:结构型模式Flyweight享元模式

    C#面向对象设计模式纵横谈(12):Flyweight 享元模式(结构型模式)

    C#面向对象设计模式纵横谈(12):Flyweight 享元模式(结构型模式)

    FlyWeight享元

    享元模式是一种设计模式,属于对象结构型模式,它的核心思想是通过共享大量细粒度对象来减少系统内存的使用,提高系统性能。在软件工程中,当系统中存在大量相似对象时,享元模式可以有效地减少内存开销,尤其在处理...

    设计模式之享元模式

    享元模式是软件设计模式中的一种结构型模式,它的主要目的是为了提高性能,尤其是在大量对象创建时。享元模式通过共享已有对象来减少内存中对象的数量,从而达到降低内存消耗的效果。这种模式适用于那些轻量级对象,...

    C++设计模式课件13_Flyweight_享元模式.pdf

    ### C++设计模式之享元模式详解 #### 一、享元模式概述 享元模式(Flyweight Pattern)是设计模式中的一种优化模式,主要用于减少创建大量相似对象所需的内存消耗。在C++程序设计中,当系统中存在大量的相同或相似...

    JAVA设计模式chm文档

    设计模式之Flyweight(享元) 行为模式: 设计模式之Template 设计模式之Memento(备忘机制) 设计模式之Observer 设计模式之Chain of Responsibility(职责链) 设计模式之Command 设计模式之State 设计模式之Strategy...

    C++设计模式编程之Flyweight享元模式结构详解

    享元模式是一种设计模式,主要用于减少对象的创建,从而提高性能和降低内存占用。在C++编程中,享元模式的应用能够帮助优化内存管理和提高程序效率。享元模式的核心思想是区分对象的内部状态(intrinsic state)和...

    Java设计模式之享元模式

    享元模式是软件设计模式中的一种结构型模式,它的核心思想是通过共享已经存在的对象来减少内存中的对象数量,从而提高系统性能。在Java中,享元模式常用于处理大量相似对象的场景,例如在图形界面中绘制大量相似的...

    设计模式的享元模式的例子

    享元模式是软件设计模式中的一种结构型模式,它的主要目的是通过共享大量细粒度对象来减少内存的使用,提高系统性能。在许多场景下,尤其是处理大量相似对象时,享元模式能显著减少内存开销。这个压缩包文件...

    设计模式文档 chm

    设计模式之Flyweight(享元) 行为模式: 设计模式之Template 设计模式之Memento(备忘机制) 设计模式之Observer 设计模式之Chain of Responsibility(职责链) 设计模式之Command 设计模式之State 设计模式之Strategy...

Global site tag (gtag.js) - Google Analytics