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

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

类型:结构型模式。

适用情况:

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

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

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

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

类图

设计模式12——结构型模式之享元模式_第1张图片

参与者:

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

示例代码:

// 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设计模式》


你可能感兴趣的:(设计模式,浅显易懂的设计模式)