设计模式12――结构型模式之享元模式

2014-11-24 03:05:53 · 作者: · 浏览: 0

定义:享元模式(Flyweight Pattern),运用共享技术有效地支持大量细粒度的对象。

类型:结构型模式。

适用情况:

  1. 一个应用程序有大量的对象。
  2. 对象的大多数状态都是外部的。
  3. 如果删除对象的外部状态,可以和相对较少的共享对象取代很多组对象。
  4. 应用程序不依赖对象的标识,即应用程序依赖于对象的抽象接口。 概述:

    Flyweight,原意为“轻量级选手”的意思。翻译者将它意为享元模式,是意译,力求能够直观地表现出此模式的目的。享,共享之意。元,基本单元的意思。享元,也就是共享基本单元,也即GoF所言的运用共享技术有效地支持大量细粒度的对象。

    享元模式的重点在于将对象的“内部状态”和“外部状态”抽象出来,内部状态存储在享元对象中,而外部状态在外部存储。这个才是享元模式的关键,网上很多文章根本没有讲透这一点。

    下面举一个示例。有一棋盘上的围棋正好是大量细粒度的对象。我们将材质、形状、制作工艺抽象为内部状态, 而围棋在棋盘上的位置是标识每一棋子的标记,故棋子的位置抽象为外部状态。而棋子只有白黑两种颜色,如果存储在外部状态里,会存两种颜色很多次。故这里,白棋、黑棋作为两个对象存在。

    类图

    \\

    参与者:< http://www.2cto.com/kf/ware/vc/" target="_blank" class="keylink">vcD4KPG9sIHR5cGU9"1">

  5. Client,调用ChessBoard得到具体的棋子对象。
  6. Chessboard,管理棋子的生成以及存储棋子的外部状态,即每个棋子的具体位置。
    1. Weiqi,围棋抽象类,即享元对象,抽象出一些内部状态来。
      1. WhiteWeiqi、BlackWeiqi,两个派生出的不同颜色的围棋,实现颜色接口。

        示例代码:

        // Flyweight类

            public abstract class Weiqi
            {
                // 内部状态
                // ...............
                // private int nSize;
        
                public abstract Color GetColor();
        
            }
        

        // 具体的Flyweight类

        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;
                }
            }
        

        // FlyweightFactory类
         public class Blessboard    {
                private List
                
                  listWhite = new List
                 
                  (); private List
                  
                    listBlack = new List
                   
                    (); 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++,抽象类一定要注意析构函数一定要是虚函数。

        优缺点:

        1. 优点,减少内存的使用。
          1. 缺点,加大了结构的复杂度,需要单独管理外部状态。

            参考资料:

            1. 《设计模式――可复用面向对象软件基础》
              1. 《大话设计模式》
                1. 《Head First设计模式》