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
        }
    }

       执行结果:

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

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

      

      修改为:

      

      结果:

  • 相关阅读:
    MySQL 多会话之间更新数据的小实例
    MySQL Profile
    MySQL Explain
    MySQL 索引
    利用网站上传漏洞使用一句话木马控制服务器
    kali之nmap
    kali之使用sqlmap进行sql注入
    kali之DVWA
    Kali安装nessus
    openvas
  • 原文地址:https://www.cnblogs.com/wskxy/p/9242874.html
Copyright © 2011-2022 走看看