页首HTML代码

Y先生的小屋

导航

结构型模式之享元模式

概述

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

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

定义

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

posted on 2016-06-09 16:15  Y.Mr  阅读(289)  评论(0编辑  收藏  举报

页脚HTML代码