结构型模式 享元模式
Definition
UML class diagram
Participants
Sample code in C#
Use sharing to support large numbers of fine-grained objects efficiently. |
Participants
The classes and/or objects participating in the Flyweight pattern are:
|
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;
{ // 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 ]); } }
{ // Methods abstract public void Operation( int extrinsicstate ); }
{ // Methods override public void Operation( int extrinsicstate ) { Console.WriteLine("ConcreteFlyweight: {0}", extrinsicstate ); } }
{ // Methods override public void Operation( int extrinsicstate ) { Console.WriteLine("UnsharedConcreteFlyweight: {0}", extrinsicstate ); } }
/// 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 );
fy.Operation( --extrinsicstate );
fz.Operation( --extrinsicstate );
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;
{ // 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; } }
{ // 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 ); }
{ // 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 ); } }
{ // 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 ); } }
{ // 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 ); } }
/// 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'};
// 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 ); } } } |