现在的位置: 首页 > 综合 > 正文

结构型模式 享元模式

2013年04月04日 ⁄ 综合 ⁄ 共 5045字 ⁄ 字号 评论关闭
Definition

Use sharing to support large numbers of fine-grained objects efficiently.

UML class diagram
flyweight[1].gif
   Participants

   The classes and/or objects participating in the Flyweight pattern are:

  • Flyweight   (Character)

    • declares an interface through which flyweights can receive and act on extrinsic state.
  • ConcreteFlyweight   (CharacterA, CharacterB, ..., CharacterZ)
    • implements the Flyweight interface and adds storage for intrinsic state, if any. A ConcreteFlyweight object must be sharable. Any state it stores must be intrinsic, that is, it must be independent of the ConcreteFlyweight object's context.
  • UnsharedConcreteFlyweight   ( not used )
    • not all Flyweight subclasses need to be shared. The Flyweight interface enables sharing, but it doesn't enforce it. It is common for UnsharedConcreteFlyweight objects to have ConcreteFlyweight objects as children at some level in the flyweight object structure (as the Row and Column classes have).
  • FlyweightFactory   (CharacterFactory)
    • creates and manages flyweight objects
    • ensures that flyweight are shared properly. When a client requests a flyweight, the FlyweightFactory objects supplies an existing instance or creates one, if none exists.
  • Client   (FlyweightApp)
    • maintains a reference to flyweight(s).
    • computes or stores the extrinsic state of flyweight(s).

Sample code in C# 
   

This structural code demonstrates the Flyweight pattern in which a relatively small number of objects is shared many times by different clients. 
   

// Flyweight pattern -- Structural example
using System;
using System.Collections;

// "FlyweightFactory"


class
FlyweightFactory

{
  // Fields
  private Hashtable flyweights = new Hashtable();

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

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

// "Flyweight"


abstract
class Flyweight

{
  // Methods
  abstract public void Operation( int extrinsicstate );
}

// "ConcreteFlyweight"


class
ConcreteFlyweight : Flyweight

{
  // Methods
  override public void Operation( int extrinsicstate )
  {
    Console.WriteLine("ConcreteFlyweight: {0}",
                                      extrinsicstate );
  }
}

// "UnsharedConcreteFlyweight"


class
UnsharedConcreteFlyweight : Flyweight

{
  // Methods
  override public void Operation( int extrinsicstate )
  {
    Console.WriteLine("UnsharedConcreteFlyweight: {0}",
                                      extrinsicstate );
  }
}

///
<summary>

/// Client test
/// </summary>
public class Client
{
  public static void Main( string[] args )
  {
    // Arbitrary extrisic 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 );
 
  }
}

This real-world code demonstrates the Flyweight pattern in which a relatively small number of Character objects is shared many times by a document that has potentially many characters.

// Flyweight pattern -- Real World example
using System;
using System.Collections;

// "FlyweightFactory"


class
CharacterFactory

{
  // Fields
  private Hashtable characters = new Hashtable();

 
// Methods
  public Character GetCharacter( char key )
  {
    // Uses "lazy initialization"
    Character character = (Character)characters[ key ];
    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

{
  // Fields
  protected char symbol;
  protected int width;
  protected int height;
  protected int ascent;
  protected int descent;
  protected int pointSize;

  // Methods
  public abstract void Draw( int pointSize );
}

// "ConcreteFlyweight"


class
CharacterA : Character

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

 
// Methods
  public override void Draw( int pointSize )
  {
    this.pointSize = pointSize;
    Console.Write( this.symbol );
  }
}

// "ConcreteFlyweight"


class
CharacterB : Character

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

 
// Methods
  public override void Draw( int pointSize )
  {
    this.pointSize = pointSize;
    Console.Write( this.symbol );
  }
}

// ... C, D, E, etc.


// "ConcreteFlyweight"


class
CharacterZ : Character

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

 
// Methods
  public override void Draw( int pointSize )
  {
    this.pointSize = pointSize;
    Console.Write( this.symbol );
  }
}

///
<summary>

///  FlyweightApp test
/// </summary>
public class FlyweightApp
{
  public static void Main( string[] args )
  {
    // Build a document with text
    char[] document = {'A','B','Z','Z','A','A'};

  
  CharacterFactory f = new CharacterFactory();


   
// extrinsic state
    int pointSize = 12;

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

抱歉!评论已关闭.