跟着《软件秘笈---设计模式那点事》学习
定义:
享元模式(英语:Flyweight Pattern)是一种软件设计模式。它使用共享物件,用来尽可能减少内存使用量以及分享资讯给尽可能多的相似物件;它适合用于只是因重复而导致使用无法令人接受的大量内存的大量物件。通常物件中的部分状态是可以分享。常见做法是把它们放在外部数据结构,当需要使用时再将它们传递给享元。
类图:
实例:
/// <summary>
/// The 'Flyweight' class.
/// </summary>
public class Character
{
// intrinsic state
protected char _symbol;
protected int _size;
protected string _font;
// extrinsic state
protected Position _position;
public void Display(Position position)
{
Console.WriteLine(
String.Format("Symbol: {0} Size: {1} Font: {2} Position: {3} {4}",
_symbol, _size, _font, position._x, position._y));
}
}
现在我们定义了一个字符享元类,其中符合、字体和字体大小都是内部状态,而位置则是外部状态。
/// <summary>
/// A 'ConcreteFlyweight' class
/// </summary>
public class CharacterA : Character
{
public CharacterA()
{
_symbol = 'A';
_size = 10;
_font = "宋体";
//_position = new Position(0, 1);
}
}
/// <summary>
/// The 'FlyweightFactory' class
/// </summary>
public class CharacterFactory
{
// Keeps the character object by specifying key/value.
private Dictionary<char, Character> _characters =
new Dictionary<char, Character>();
public Character this[char key]
{
get
{
Character character = null;
// Checked the character whether existed or not,
// if the character existed, then directly returns,
// otherwise, instantiates a character object.
if (_characters.ContainsKey(key))
{
character = _characters[key];
}
else
{
string name = this.GetType().Namespace + "." +
"Character" + key.ToString();
character = Activator.CreateInstance(
Type.GetType(name)) as Character;
_characters.Add(key, character);
}
return character;
}
}
}
/// <summary>
/// The client.
/// </summary>
/// <param name="args">The args.</param>
[STAThread]
static void Main(string[] args)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new FrmFlyweight());
string text = "ABZABBZZ";
char[] letters = text.ToCharArray();
var characterFactory = new CharacterFactory();
// Creates random position ranges 0 to 100.
var rd = new Random();
foreach (char c in letters)
{
Character character = characterFactory[c];
var p = new Position(rd.Next(0, 100), rd.Next(0, 100));
character.Display(p);
}
Console.ReadKey();
}
使用场合:
1) 一个应用程序使用了大量的对象。
2) 完全由于使用大量的对象,造成很大的存储开销。
3) 对象的大多数状态都可变为外部状态。
4) 如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象。
5) 应用程序不依赖对象标识。
一句话总结:
运用共享技术有效的支持大量细粒度的对象。
Java SDK中的原型模式:
参考资料:
《软件秘笈---设计模式那点事》