• 结构型模式之享元模式


    概述

     当一个软件系统在运行时产生的对象数量太多,将导致运行代价过高,带来系统性能下降等问题。

    我们可以将具有相同内部状态的对象存储在享元池中,享元池中的对象是可以实现共享的,需要的时候就将对象从享元池中取出,实现对象的复用。通过向取出的对象注入不同的外部状态,可以得到一系列相似的对象,而这些对象在内存中实际上只存储一份。

    定义

    享元模式(Flyweight Pattern):运用共享技术有效地支持大量细粒度对象的复用。系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用。由于享元模式要求能够共享的对象必须是细粒度对象,因此它又称为轻量级模式,它是一种对象结构型模式。

    实现

    围棋接口类

        /// <summary>
        /// 围棋接口
        /// </summary>
        public interface IgoChessman
        {
            void Display(Coordinates coordinates);
        }

    黑棋子类

        /// <summary>
        /// 黑棋子
        /// </summary>
        public class BlackIgoChessman : IgoChessman
        {
            public void Display(Coordinates coordinates)
            {
                Console.WriteLine("黑棋子,当前坐标为:x-{0},y-{1}", coordinates.x, coordinates.y);
            }
        }

    白棋子类

        /// <summary>
        /// 白棋子
        /// </summary>
        public class WhiteIgoChessman : IgoChessman
        {
            public void Display(Coordinates coordinates)
            {
                Console.WriteLine("白棋子,当前坐标为:x-{0},y-{1}", coordinates.x, coordinates.y);
            }
        }

    享元工厂类

        public class IgoChessmanFactory
        {
            private static IgoChessmanFactory fac = new IgoChessmanFactory();
            /// <summary>
            /// 共享池,存放需要被共享的黑白棋子对象
            /// </summary>
            private Dictionary<string, IgoChessman> poor = new Dictionary<string, IgoChessman>()
            {
                { "black",new BlackIgoChessman()},
                { "white",new WhiteIgoChessman()}
            };
            private IgoChessmanFactory() { }
    
            public static IgoChessmanFactory GetInstance()
            {
                return fac;
            }
    
            public IgoChessman GetIgoChessman(string color)
            {
                IgoChessman igoChessman;
                poor.TryGetValue(color, out igoChessman);
                return igoChessman;
            }
        }

    客户端

        class Program
        {
            static void Main(string[] args)
            {
                var facroty = IgoChessmanFactory.GetInstance();
                //通过工厂从享元池中复用对象
                var igo1 = facroty.GetIgoChessman("black");
                var igo2 = facroty.GetIgoChessman("black");
                var igo3 = facroty.GetIgoChessman("black");
                var igo4 = facroty.GetIgoChessman("white");
                var igo5 = facroty.GetIgoChessman("white");
                //注入外部不共享状态
                igo1.Display(new Coordinates(0, 1));
                igo2.Display(new Coordinates(0, 2));
                igo3.Display(new Coordinates(0, 3));
                igo4.Display(new Coordinates(0, 4));
                igo5.Display(new Coordinates(0, 5));
                Console.ReadLine();
            }
        }

    总结

    主要优点

    1、可以极大减少内存中对象的数量,使得相同或相似对象在内存中只保存一份,从而可以节约系统资源,提高系统性能。

    2、享元模式的外部状态相对独立,而且不会影响其内部状态,从而使得享元对象可以在不同的环境中被共享。

    主要缺点

    1、享元模式使得系统变得复杂,需要分离出内部状态和外部状态,这使得程序的逻辑复杂化。

    2、为了使对象可以共享,享元模式需要将享元对象的部分状态外部化,而读取外部状态将使得运行时间变长。

    适用场景

    1、一个系统有大量相同或者相似的对象,造成内存的大量耗费。

    2、 对象的大部分状态都可以外部化,可以将这些外部状态传入对象中。

    3、在使用享元模式时需要维护一个存储享元对象的享元池,而这需要耗费一定的系统资源,因此,应当在需要多次重复使用享元对象时才值得使用享元模式

  • 相关阅读:
    drop table 、delete table和truncate table的区别
    润乾报表 删除导出excel弹出框里的选项
    学习笔记: 委托解析和封装,事件及应用
    学习笔记: 特性Attribute详解,应用封装
    学习笔记: 反射应用、原理,完成扩展,emit动态代码
    学习笔记: 泛型应用、原理、协变逆变、泛型缓存
    jmeter4.x centos7部署笔记
    rabbitmq3.7.5 centos7 集群部署笔记
    rabbitmq3.8.3 centos7 安装笔记
    UVA-12436 Rip Van Winkle's Code (线段树区间更新)
  • 原文地址:https://www.cnblogs.com/Jabben_Yi/p/5572430.html
Copyright © 2020-2023  润新知