C++ Programmer's Cookbook

{C++ 基础} {C++ 高级} {C#界面,C++核心算法} {设计模式} {C#基础}

模式设计c#--结构型--flyweight

名称 Flyweight
结构 o_flyweight.bmp
意图 运用共享技术有效地支持大量细粒度的对象。
适用性
  • 一个应用程序使用了大量的对象。
  • 完全由于使用大量的对象,造成很大的存储开销。
  • 对象的大多数状态都可变为外部状态。
  • 如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象。
  • 应用程序不依赖于对象标识。由于F l y w e i g h t 对象可以被共享,对于概念上明显有别的对象,标识测试将返回真值。
Code Example
将内部状态(不会发生变化的状态)与外部状态(可能发生变化的状态)分离,这样不会发生变化的部分可以抽取出来共享,而可能发生变化的部分由客户维护。
// Flyweight pattern -- Structural example  


using System;
using System.Collections;

namespace DoFactory.GangOfFour.Flyweight.Structural
{
  
// MainApp test application 

  
class MainApp
  
{
    
static void Main()
    
{
      
// Arbitrary extrinsic state 
      int extrinsicstate = 22;
    
      FlyweightFactory f 
= new FlyweightFactory();

      
// Work with different flyweight instances 
      Flyweight fx = f.GetFlyweight("X");
      fx.Operation(
--extrinsicstate);

      Flyweight fy 
= f.GetFlyweight("Y");
      fy.Operation(
--extrinsicstate);

      Flyweight fz 
= f.GetFlyweight("Z");
      fz.Operation(
--extrinsicstate);

      UnsharedConcreteFlyweight fu 
= new 
        UnsharedConcreteFlyweight();

      fu.Operation(
--extrinsicstate);

      
// Wait for user 
      Console.Read();
    }

  }


  
// "FlyweightFactory" 

  
class FlyweightFactory 
  
{
    
private Hashtable flyweights = new Hashtable();

    
// Constructor 
    public FlyweightFactory()
    
{
      flyweights.Add(
"X"new ConcreteFlyweight());    
      flyweights.Add(
"Y"new ConcreteFlyweight());
      flyweights.Add(
"Z"new ConcreteFlyweight());
    }


    
public Flyweight GetFlyweight(string key)
    
{
      
return((Flyweight)flyweights[key]); 
    }

  }


  
// "Flyweight" 

  
abstract class Flyweight 
  
{
    
public abstract void Operation(int extrinsicstate);
  }


  
// "ConcreteFlyweight" 

  
class ConcreteFlyweight : Flyweight
  
{
    
public override void Operation(int extrinsicstate)
    
{
      Console.WriteLine(
"ConcreteFlyweight: " + extrinsicstate);
    }

  }


  
// "UnsharedConcreteFlyweight" 

  
class UnsharedConcreteFlyweight : Flyweight
  
{
    
public override void Operation(int extrinsicstate)
    
{
      Console.WriteLine(
"UnsharedConcreteFlyweight: " + 
        extrinsicstate);
    }

  }

}

 


享元模式应当在什么情况下使用

当以下所有的条件都满足时,可以考虑使用享元模式:

  • 一个系统有大量的对象。
  • 这些对象耗费大量的内存。
  • 这些对象的状态中的大部分都可以外部化。
  • 这些对象可以按照内蕴状态分成很多的组,当把外蕴对象从对象中剔除时,每一个组都可以仅用一个对象代替。
  • 软件系统不依赖于这些对象的身份,换言之,这些对象可以是不可分辨的。

满足以上的这些条件的系统可以使用享元对象。

最后,使用享元模式需要维护一个记录了系统已有的所有享元的表,而这需要耗费资源。因此,应当在有足够多的享元实例可供共享时才值得使用享元模式。


八、 享元模式的优点和缺点

享元模式的优点在于它大幅度地降低内存中对象的数量。但是,它做到这一点所付出的代价也是很高的:

  • 享元模式使得系统更加复杂。为了使对象可以共享,需要将一些状态外部化,这使得程序的逻辑复杂化。
  • 享元模式将享元对象的状态外部化,而读取外部状态使得运行时间稍微变长。

享元模式的应用

享元模式在编辑器系统中大量使用。一个文本编辑器往往会提供很多种字体,而通常的做法就是将每一个字母做成一个享元对象。享元对象的内蕴状态就是这个字母,而字母在文本中的位置和字模风格等其他信息则是外蕴状态。比如,字母a可能出现在文本的很多地方,虽然这些字母a的位置和字模风格不同,但是所有这些地方使用的都是同一个字母对象。这样一来,字母对象就可以在整个系统中共享。

// Flyweight pattern -- Real World example  


using System;
using System.Collections;

namespace DoFactory.GangOfFour.Flyweight.RealWorld
{

  
// MainApp test application 

  
class MainApp
  
{
    
static void Main()
    
{
      
// Build a document with text 
      string document = "AAZZBBZB";
      
char[] chars = document.ToCharArray();

      CharacterFactory f 
= new CharacterFactory();

      
// extrinsic state 
      int pointSize = 10;

      
// For each character use a flyweight object 
      foreach (char c in chars)
      
{
        pointSize
++;
        Character character 
= f.GetCharacter(c);
        character.Display(pointSize);
      }


      
// Wait for user 
      Console.Read();
    }

  }


  
// "FlyweightFactory" 

  
class CharacterFactory
  
{
    
private Hashtable characters = new Hashtable();

    
public Character GetCharacter(char key)
    
{
      
// Uses "lazy initialization" 
      Character character = characters[key] as Character;
      
if (character == null)
      
{
        
switch (key)
        
{
          
case 'A': character = new CharacterA(); break;
          
case 'B': character = new CharacterB(); break;
            
// 
          case 'Z': character = new CharacterZ(); break;
        }

        characters.Add(key, character);
      }

      
return character;
    }

  }


  
// "Flyweight" 

  
abstract class Character
  
{
    
protected char symbol;
    
protected int width;
    
protected int height;
    
protected int ascent;
    
protected int descent;
    
protected int pointSize;

    
public abstract void Display(int pointSize);
  }


  
// "ConcreteFlyweight" 

  
class CharacterA : Character
  
{
    
// Constructor 
    public CharacterA()
    
{
      
this.symbol = 'A';
      
this.height = 100;
      
this.width = 120;
      
this.ascent = 70;
      
this.descent = 0;
    }


    
public override void Display(int pointSize)
    
{
      
this.pointSize = pointSize;
      Console.WriteLine(
this.symbol + 
        
" (pointsize " + this.pointSize + ")");
    }

  }


  
// "ConcreteFlyweight" 

  
class CharacterB : Character
  
{
    
// Constructor 
    public CharacterB()
    
{
      
this.symbol = 'B';
      
this.height = 100;
      
this.width = 140;
      
this.ascent = 72;
      
this.descent = 0;
    }


    
public override void Display(int pointSize)
    
{
      
this.pointSize = pointSize;
      Console.WriteLine(
this.symbol + 
        
" (pointsize " + this.pointSize + ")");
    }


  }


  
//  C, D, E, etc. 

  
// "ConcreteFlyweight" 

  
class CharacterZ : Character
  
{
    
// Constructor 
    public CharacterZ()
    
{
      
this.symbol = 'Z';
      
this.height = 100;
      
this.width = 100;
      
this.ascent = 68;
      
this.descent = 0;
    }


    
public override void Display(int pointSize)
    
{
      
this.pointSize = pointSize;
      Console.WriteLine(
this.symbol + 
        
" (pointsize " + this.pointSize + ")");
    }

  }

}

 

Output
A (pointsize 11)
A (pointsize 12)
Z (pointsize 13)
Z (pointsize 14)
B (pointsize 15)
B (pointsize 16)
Z (pointsize 17)
B (pointsize 18)

posted on 2006-01-03 15:50 梦在天涯 阅读(712) 评论(0)  编辑 收藏 引用 所属分类: Design pattern


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理


公告

EMail:itech001#126.com

导航

统计

  • 随笔 - 461
  • 文章 - 4
  • 评论 - 746
  • 引用 - 0

常用链接

随笔分类

随笔档案

收藏夹

Blogs

c#(csharp)

C++(cpp)

Enlish

Forums(bbs)

My self

Often go

Useful Webs

Xml/Uml/html

搜索

  •  

积分与排名

  • 积分 - 1796270
  • 排名 - 5

最新评论

阅读排行榜