• 结构型模式之享元模式


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

    类型:结构型模式。

    适用情况:

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

    概述:

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

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

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

    类图

    参与者:

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

    示例代码:

    // Flyweight类

    1. public abstract class Weiqi  
    2. {  
    3.     // 内部状态  
    4.     // ...............  
    5.     // private int nSize;  
    6.   
    7.     public abstract Color GetColor();  
    8.   
    9. }  

    // 具体的Flyweight类

    1. public class WhiteWeiqi : Weiqi    {  
    2.         public override Color GetColor()  
    3.         {  
    4.             Console.WriteLine("White");  
    5.             return Color.White;  
    6.         }  
    7.     }  
    8.   
    9.     public class BlackWeiqi : Weiqi  
    10.     {  
    11.         public override Color GetColor()  
    12.         {  
    13.             Console.WriteLine("Black");  
    14.             return Color.Black;  
    15.         }  
    16.     }  

    // FlyweightFactory类

    1. public class Blessboard    {  
    2.        private List<Point> listWhite = new List<Point>();  
    3.        private List<Point> listBlack = new List<Point>();  
    4.        private WhiteWeiqi wWeiqi;  
    5.        private BlackWeiqi bWeiqi;  
    6.   
    7.        public Blessboard()  
    8.        {  
    9.            wWeiqi = new WhiteWeiqi();  
    10.            bWeiqi = new BlackWeiqi();  
    11.        }  
    12.   
    13.        public Weiqi Produce(bool bWthite, Point pt)  
    14.        {  
    15.            if (bWthite)  
    16.            {  
    17.                listWhite.Add(pt);  
    18.   
    19.                return bWeiqi;  
    20.            }  
    21.            else  
    22.            {  
    23.                listBlack.Add(pt);  
    24.   
    25.                return bWeiqi;  
    26.            }  
    27.        }  
    28.   
    29.        public Weiqi GetProduce(Point pt)  
    30.        {  
    31.            foreach (Point p in listWhite)  
    32.            {  
    33.                if (p.Equals(pt))  
    34.                {  
    35.                    return wWeiqi;  
    36.                }  
    37.            }  
    38.   
    39.            foreach (Point p in listBlack)  
    40.            {  
    41.                if (p.Equals(pt))  
    42.                {  
    43.                    return bWeiqi;  
    44.                }  
    45.            }  
    46.   
    47.            return null;  
    48.        }  
    49.    }  

    // Client类

    1. class Program    {  
    2.         static void Main(string[] args)  
    3.         {  
    4.             Blessboard bloard = new Blessboard();  
    5.   
    6.             // 生成棋子  
    7.             bloard.Produce(true, new Point(1, 3));  
    8.             bloard.Produce(false, new Point(2, 3));  
    9.             bloard.Produce(true, new Point(1, 4));  
    10.             bloard.Produce(false, new Point(2, 4));  
    11.   
    12.             // 查询棋子黑白  
    13.             Weiqi weiqi = bloard.GetProduce(new Point(2, 4));  
    14.             Color color = weiqi.GetColor();  
    15.   
    16.             weiqi = bloard.GetProduce(new Point(1, 4));  
    17.             color = weiqi.GetColor();  
    18.         }  
    19.     }  

    注意:如果是C++,抽象类一定要注意析构函数一定要是虚函数。

    优缺点:

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

    参考资料:

    1. 《设计模式——可复用面向对象软件基础》
    1. 《大话设计模式》
    1. 《Head First设计模式》
  • 相关阅读:
    组件传值---组件与弹窗组件传值
    elementUI拿到当前表格行的数据的另一种写法
    elementUi-复选框,使用v-for循环出来的复选框,默认多个值为勾选状态
    点击事件,根据不同的下标实现切换不同的内容
    elementUI表格行的点击事件,点击表格,拿到当前行的数据
    在使用element-ui搭建的表格中,实现点击"定位"按钮后,屏幕滚动到对应行的位置
    renren-fast-vue-动态路由-添加路由-方式一(直接在原有结构上添加)
    renren-fast-vue-动态路由
    vue-element-admin打包后白屏的问题
    2月20日-寒假学习进度20
  • 原文地址:https://www.cnblogs.com/yulei126/p/6756227.html
Copyright © 2020-2023  润新知