1: // Flyweight pattern -- Real World example
2:
3: using System;
4: using System.Collections.Generic;
5:
6: namespace DoFactory.GangOfFour.Flyweight.RealWorld
7: {
8: /// <summary>
9: /// MainApp startup class for Real-World
10: /// Flyweight Design Pattern.
11: /// </summary>
12: internal class MainApp
13: {
14: /// <summary>
15: /// Entry point into console application.
16: /// </summary>
17: private static void Main()
18: {
19: // Build a document with text
20: string document = "AAZZBBZB";
21: char[] chars = document.ToCharArray();
22: CharacterFactory factory = new CharacterFactory();
23: // extrinsic state
24: int pointSize = 10;
25: // For each character use a flyweight object
26: foreach (char c in chars)
27: {
28: pointSize++;
29: Character character = factory.GetCharacter(c);
30: character.Display(pointSize);
31: }
32:
33: // Wait for user
34: Console.ReadKey();
35: }
36: }
37:
38:
39: /// <summary>
40: /// The 'FlyweightFactory' class
41: /// </summary>
42: internal class CharacterFactory
43: {
44: private Dictionary<char, Character> _characters =
45: new Dictionary<char, Character>();
46:
47: public Character GetCharacter(char key)
48: {
49: // Uses "lazy initialization"
50: Character character = null;
51: if (_characters.ContainsKey(key))
52: {
53: character = _characters[key];
54: }
55: else
56: {
57: switch (key)
58: {
59: case 'A':
60: character = new CharacterA();
61: break;
62: case 'B':
63: character = new CharacterB();
64: break;
65:
66: //...
67:
68: case 'Z':
69: character = new CharacterZ();
70: break;
71: }
72: _characters.Add(key, character);
73: }
74: return character;
75: }
76: }
77:
78: /// <summary>
79: /// The 'Flyweight' abstract class
80: /// </summary>
81: internal abstract class Character
82: {
83: protected char symbol;
84: protected int width;
85: protected int height;
86: protected int ascent;
87: protected int descent;
88: protected int pointSize;
89:
90: public abstract void Display(int pointSize);
91: }
92:
93: /// <summary>
94: /// A 'ConcreteFlyweight' class
95: /// </summary>
96: internal class CharacterA : Character
97: {
98: // Constructor
99: public CharacterA()
100: {
101: this.symbol = 'A';
102: this.height = 100;
103: this.width = 120;
104: this.ascent = 70;
105: this.descent = 0;
106: }
107:
108:
109: public override void Display(int pointSize)
110: {
111: this.pointSize = pointSize;
112: Console.WriteLine(this.symbol +
113: " (pointsize " + this.pointSize + ")");
114: }
115: }
116:
117: /// <summary>
118: /// A 'ConcreteFlyweight' class
119: /// </summary>
120: internal class CharacterB : Character
121: {
122: // Constructor
123: public CharacterB()
124: {
125: this.symbol = 'B';
126: this.height = 100;
127: this.width = 140;
128: this.ascent = 72;
129: this.descent = 0;
130: }
131:
132:
133: public override void Display(int pointSize)
134: {
135: this.pointSize = pointSize;
136: Console.WriteLine(this.symbol +
137: " (pointsize " + this.pointSize + ")");
138: }
139: }
140:
141: // ... C, D, E, etc.
142:
143: /// <summary>
144: /// A 'ConcreteFlyweight' class
145: /// </summary>
146: internal class CharacterZ : Character
147: {
148: // Constructor
149:
150: public CharacterZ()
151: {
152: this.symbol = 'Z';
153: this.height = 100;
154: this.width = 100;
155: this.ascent = 68;
156: this.descent = 0;
157: }
158:
159:
160: public override void Display(int pointSize)
161: {
162: this.pointSize = pointSize;
163: Console.WriteLine(this.symbol +
164: " (pointsize " + this.pointSize + ")");
165: }
166: }
167: }