享元模式

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了享元模式相关的知识,希望对你有一定的参考价值。

享元模式 要解决的问题是对象重复创建的问题!这一点你会想到,我用单例模式可以解决。是的。

享元模式和单例模式都是要维护对象的唯一性:

享元模式和单例模式的区别在哪里呢?

享元模式由对象的外部负责(通常用工厂)维护对象的唯一性

单例模式是对象自身负责维护对象的唯一性

拼字游戏:

例1:

        static void Main(string[] args)
        {
            IWord s1 = new S();
            IWord e = new E();
            IWord s2 = new S();
            IWord s3 = new S();
            IWord i = new I();
            IWord o = new O();
            IWord n = new N();

            Console.WriteLine("拼词游戏:{0}{1}{2}{3}{4}{5}{6}", s1.GetWord(), e.GetWord(), s2.GetWord(), s3.GetWord(), i.GetWord(), o.GetWord(), n.GetWord());
            Console.Read();
        }
    public abstract class IWord
    {
        public abstract string GetWord();
    }

 

    public class S : IWord
    {
        public S()
        {
            Console.WriteLine("S被创建");
        }
        public override string GetWord()
        {
            return "s";
        }
    }

 

 

例2:

        static void Main(string[] args)
        {
            IWord s = new S();
            IWord e = new E();
            IWord i = new I();
            IWord o = new O();
            IWord n = new N();

            Console.WriteLine("拼词游戏:{0}{1}{2}{3}{4}{5}{6}", s.GetWord(), e.GetWord(), s.GetWord(), s.GetWord(), i.GetWord(), o.GetWord(), n.GetWord());
            Console.Read();
        }

S在例1中实例了3次,例2中只实例了一次。效果是相同的。例2比例1更节省内存和空间,与维护性

例3:

        static void Main(string[] args)
        {
            IWord s = WordFactory.GetWord(WordEnum.s);
            IWord e = WordFactory.GetWord(WordEnum.e);
            IWord i = WordFactory.GetWord(WordEnum.i);
            IWord o = WordFactory.GetWord(WordEnum.o);
            IWord n = WordFactory.GetWord(WordEnum.n);

            Console.WriteLine("拼词游戏:{0}{1}{2}{3}{4}{5}{6}", s.GetWord(), e.GetWord(), s.GetWord(), s.GetWord(), i.GetWord(), o.GetWord(), n.GetWord());
            Console.Read();
        }

 

 public class WordFactory
    {

        /// <summary>
        /// 定义一个静态字典,用来维护确保对象实例只有一个
        /// </summary>
        static Dictionary<string, IWord> DictionaryWord = new Dictionary<string, IWord>();

        /// <summary>
        /// 这个锁是为了多线程,确定同时只有一个线程能够访问
        /// </summary>
        static object objectLock = new object();

        public static IWord GetWord(WordEnum wordenum)
        {
            switch (wordenum)
            {
                case WordEnum.s:
                    ///如果对象已经存在,那么线程就不用等待锁的环节,直接返回,这样节省了线程锁的开销
                    if (!DictionaryWord.ContainsKey(wordenum.ToString()))
                    {
                        ///锁定,确保只有一个线程可以访问
                        lock (objectLock)
                        {
                            ///检查是否存在
                            if (!DictionaryWord.ContainsKey(wordenum.ToString()))
                            {
                                ///如果不存在就创建
                                DictionaryWord.Add(wordenum.ToString(), new S());
                            }
                        }
                    }
                    ///返回对象
                    return DictionaryWord[wordenum.ToString()];

                case WordEnum.e:
                    return new E();
                case WordEnum.i:
                    return new I();
                case WordEnum.o:
                    return new O();
                case WordEnum.n:
                    return new N();
                default:
                    throw new Exception("错误");
            }

        }
    }

    public enum WordEnum
    {
        s,
        e,
        i,
        o,
        n
    }

S对象被使用了3次,只被创建了1次

例3用的是工厂来负责管理要创建的对象。同时支持多线程下的享元模式

以上是关于享元模式的主要内容,如果未能解决你的问题,请参考以下文章

11-享元(Flyweight)模式Ruby实现

设计模式课程 设计模式精讲 13-1 享元模式coding

常用设计模式系列之——享元模式

23种设计模式之享元模式代码实例

享元模式

享元模式(Flyweight)