zoukankan      html  css  js  c++  java
  • 享元模式

    1.简介

      享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式。享元模式尝试重用现有的同类对象,如果未找到匹配的对象,则创建新对象。

      我们这里新建H、E、L、O四个类,每个类返回对应的字母,用来打印HELLO。

      首先,新建一个抽象类,用来规定H、E、L、O四个类需要有相同的操作DisPlay

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace FlyweightPattern
    {
        public abstract class BaseWord
        {
            public abstract string DisPlay();
        }
    }

      H类

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    
    namespace FlyweightPattern
    {
        class H:BaseWord
        {
            public H()
            {
                Thread.Sleep(500);
                Console.WriteLine("字母H被构造");
            }
            public override string DisPlay()
            {
                return "H";
            }
        }
    }

      E类

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Threading;
    namespace FlyweightPattern
    {
        class E : BaseWord
        {
            public E()
            {
                Thread.Sleep(500);
                Console.WriteLine("字母E被构造");
            }
            public override string DisPlay()
            {
                return "E";
            }
        }
    }

      L类

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Threading;
    namespace FlyweightPattern
    {
        class L:BaseWord
        {
            public L()
            {
                Thread.Sleep(500);
                Console.WriteLine("字母L被构造");
            }
            public override string DisPlay()
            {
                return "L";
            }
        }
    }

      O类

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    
    namespace FlyweightPattern
    {
        class O:BaseWord
        {
            public O()
            {
                Thread.Sleep(500);
                Console.WriteLine("字母O被构造");
            }
            public override string DisPlay()
            {
                return "O";
            }
        }
    }

      接下来是享元模式的核心

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace FlyweightPattern
    {
        public class FlyWeightFactory//享元工厂
        {
            private static Dictionary<WordType, BaseWord> _BaseWorldDictionary = new Dictionary<WordType, BaseWord>();//用字典保存关键字和类的实例
            public static BaseWord GetWord(WordType wordType)
            {
                BaseWord baseWord = null;
                if (_BaseWorldDictionary.ContainsKey(wordType))//如果字典中已经有这个实例,就直接使用,没有就新增
                {
                    baseWord = _BaseWorldDictionary[wordType];
                }
                else
                {
                    switch (wordType)
                    {
                        case WordType.E: baseWord = new E(); break;
                        case WordType.H: baseWord = new H(); break;
                        case WordType.L: baseWord = new L(); break;
                        case WordType.O: baseWord = new O(); break;
                        default:throw new Exception("wrong wordType");
                    }
                    _BaseWorldDictionary.Add(wordType, baseWord);
                }
                return baseWord;
            }
        }
        public enum WordType
        {
            H,E,L,O
        }
    }

      Program:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace FlyweightPattern
    {
        class Program
        {
            static void Main(string[] args)
            {
                show1();
                show2();
                Console.Read();
            }
            static void show1()
            {
                Console.WriteLine("--------------------show1-----------------------");
                BaseWord baseWord1 = FlyWeightFactory.GetWord(WordType.H);
                BaseWord baseWord2 = FlyWeightFactory.GetWord(WordType.E);
                BaseWord baseWord3 = FlyWeightFactory.GetWord(WordType.L);
                BaseWord baseWord4 = FlyWeightFactory.GetWord(WordType.L);
                BaseWord baseWord5 = FlyWeightFactory.GetWord(WordType.O);
                Console.Write(baseWord1.DisPlay());
                Console.Write(baseWord2.DisPlay());
                Console.Write(baseWord3.DisPlay());
                Console.Write(baseWord4.DisPlay());
                Console.Write(baseWord5.DisPlay());
                Console.WriteLine();
            }
    
            static void show2()
            {
                Console.WriteLine("--------------------show2-----------------------");
                BaseWord baseWord1 = FlyWeightFactory.GetWord(WordType.H);
                BaseWord baseWord2 = FlyWeightFactory.GetWord(WordType.E);
                BaseWord baseWord3 = FlyWeightFactory.GetWord(WordType.L);
                BaseWord baseWord4 = FlyWeightFactory.GetWord(WordType.L);
                BaseWord baseWord5 = FlyWeightFactory.GetWord(WordType.O);
                Console.Write(baseWord1.DisPlay());
                Console.Write(baseWord2.DisPlay());
                Console.Write(baseWord3.DisPlay());
                Console.Write(baseWord4.DisPlay());
                Console.Write(baseWord5.DisPlay());
                Console.WriteLine();
            }
        }
    }

     2.多线程享元模式

      当我们使用多线程的时候,上面的例子并不稳定

      很大可能会发生错误

      对Program的Main函数进行修改,启用多线程

    static void Main(string[] args)
            {
                new Action(show1).BeginInvoke(null, null);
                new Action(show2).BeginInvoke(null, null);
    
                Console.Read();
            }

      执行的时候两个线程会同步进行

      结果如下:

         H类被实例化了两次,字典添加相同的键,发生错误

      可以对享元工厂进行双if+lock锁来解决这个问题

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace FlyweightPattern
    {
        public class FlyWeightFactory//享元工厂
        {
            static object FlyWeight_Lock = new object();//定义一个静态object参数,用来做lock的参数
            private static Dictionary<WordType, BaseWord> _BaseWorldDictionary = new Dictionary<WordType, BaseWord>();//用字典保存关键字和类的实例
            public static BaseWord GetWord(WordType wordType)
            {
                BaseWord baseWord = null;
                if (_BaseWorldDictionary.ContainsKey(wordType))
                {
                    baseWord = _BaseWorldDictionary[wordType];
                }
                else
                {
                    lock (FlyWeight_Lock)
                    {
                        if (_BaseWorldDictionary.ContainsKey(wordType))//如果字典中已经有这个实力,就直接使用,没有就新增
                        {
                            baseWord = _BaseWorldDictionary[wordType];
                        }
                        else
                        {
                            switch (wordType)
                            {
                                case WordType.E: baseWord = new E(); break;
                                case WordType.H: baseWord = new H(); break;
                                case WordType.L: baseWord = new L(); break;
                                case WordType.O: baseWord = new O(); break;
                                default: throw new Exception("wrong wordType");
                            }
                            _BaseWorldDictionary.Add(wordType, baseWord);
                        }
                    }
                }
                return baseWord;
            }
        }
        public enum WordType
        {
            H,E,L,O
        }
    }

       执行结果:

      因为多线程的无序性,打印结果并不是我们期待的结果

      可以对打印代码进行一下修改

      

      修改为:

      

      结果:

  • 相关阅读:
    173. Binary Search Tree Iterator
    199. Binary Tree Right Side View
    230. Kth Smallest Element in a BST
    236. Lowest Common Ancestor of a Binary Tree
    337. House Robber III
    449. Serialize and Deserialize BST
    508. Most Frequent Subtree Sum
    513. Find Bottom Left Tree Value
    129. Sum Root to Leaf Numbers
    652. Find Duplicate Subtrees
  • 原文地址:https://www.cnblogs.com/wskxy/p/9242874.html
Copyright © 2011-2022 走看看