定义:享元模式(Flyweight Pattern),运用共享技术有效地支持大量细粒度的对象。
类型:结构型模式。
适用情况:
Flyweight,原意为“轻量级选手”的意思。翻译者将它意为享元模式,是意译,力求能够直观地表现出此模式的目的。享,共享之意。元,基本单元的意思。享元,也就是共享基本单元,也即GoF所言的运用共享技术有效地支持大量细粒度的对象。
享元模式的重点在于将对象的“内部状态”和“外部状态”抽象出来,内部状态存储在享元对象中,而外部状态在外部存储。这个才是享元模式的关键,网上很多文章根本没有讲透这一点。
下面举一个示例。有一棋盘上的围棋正好是大量细粒度的对象。我们将材质、形状、制作工艺抽象为内部状态, 而围棋在棋盘上的位置是标识每一棋子的标记,故棋子的位置抽象为外部状态。而棋子只有白黑两种颜色,如果存储在外部状态里,会存两种颜色很多次。故这里,白棋、黑棋作为两个对象存在。
类图:
参与者:
示例代码:
// Flyweight类
public abstract class Weiqi { // 内部状态 // ............... // private int nSize; public abstract Color GetColor(); }
public class WhiteWeiqi : Weiqi { public override Color GetColor() { Console.WriteLine("White"); return Color.White; } } public class BlackWeiqi : Weiqi { public override Color GetColor() { Console.WriteLine("Black"); return Color.Black; } }
public class Blessboard { private List<Point> listWhite = new List<Point>(); private List<Point> listBlack = new List<Point>(); private WhiteWeiqi wWeiqi; private BlackWeiqi bWeiqi; public Blessboard() { wWeiqi = new WhiteWeiqi(); bWeiqi = new BlackWeiqi(); } public Weiqi Produce(bool bWthite, Point pt) { if (bWthite) { listWhite.Add(pt); return bWeiqi; } else { listBlack.Add(pt); return bWeiqi; } } public Weiqi GetProduce(Point pt) { foreach (Point p in listWhite) { if (p.Equals(pt)) { return wWeiqi; } } foreach (Point p in listBlack) { if (p.Equals(pt)) { return bWeiqi; } } return null; } }
// Client类
class Program { static void Main(string[] args) { Blessboard bloard = new Blessboard(); // 生成棋子 bloard.Produce(true, new Point(1, 3)); bloard.Produce(false, new Point(2, 3)); bloard.Produce(true, new Point(1, 4)); bloard.Produce(false, new Point(2, 4)); // 查询棋子黑白 Weiqi weiqi = bloard.GetProduce(new Point(2, 4)); Color color = weiqi.GetColor(); weiqi = bloard.GetProduce(new Point(1, 4)); color = weiqi.GetColor(); } }
注意:如果是C++,抽象类一定要注意析构函数一定要是虚函数。
优缺点:
参考资料: