• 享元模式(25)


    今天我们来讲一下享元模式。

    我们在工作之余可能会接一些私活,比如,帮人开发一个网站,帮人开发一个私人博客。随着私活的增多,会发现,有很多项目是有相同之处的,比如,帮人开发一个网站,你会发现,之前做的一些网站的代码单元是可以公共的。所以,即便是有很多的私活,我们不要盲目的去做一些项目,我们要善于发现,善于总结,这样会大大提高我们的效率。

    我们将上述场景用代码体现一下就如同下面代码:

     1     /// <summary>
     2     /// 网站类
     3     /// </summary>
     4     class WebSite
     5     {
     6         private string name = "";
     7 
     8         public WebSite(string name)
     9         {
    10             this.name = name;
    11         }
    12 
    13         public void Use()
    14         {
    15             Console.WriteLine($"网站分类:{name}");
    16         }
    17     }

    客户端调用:

     1         public static void Main()
     2         {
     3             WebSite fx = new WebSite("门户网站");
     4             fx.Use();
     5 
     6             WebSite fy = new WebSite("门户网站");
     7             fy.Use();
     8 
     9             WebSite fz = new WebSite("门户网站");
    10             fz.Use();
    11 
    12             WebSite fl = new WebSite("个人博客");
    13             fl.Use();
    14 
    15             WebSite fm = new WebSite("个人博客");
    16             fm.Use();
    17 
    18             WebSite fn = new WebSite("个人博客");
    19             fn.Use();
    20 
    21             Console.ReadKey();
    22         }

    在弄清楚如何共享代码之前,我们先来谈一下今天我们要讲的设计模式——享元模式。

    享元模式,运用共享技术有效地支持大量细粒度地对象,所有具体享元类地超类或接口,通过这个接口,可以接受并作用于外部状态。

    我们再来看一下它的结构代码:

     1     //所有具体享元类地超类或接口,通过这个接口,可以接受并作用于外部状态
     2     abstract class Flyweight
     3     {
     4         public abstract void Operation(int extrinsicstate);
     5     }
     6     //继承Flyweight实现Flyweight接口
     7     class ConcreteFlyweight : Flyweight
     8     {
     9         public override void Operation(int extrinsicstate)
    10         {
    11             Console.WriteLine($"具体Flyweight:{extrinsicstate}");
    12         }
    13     }
    14     //不需要共享Flyweight子类,因为Flyweight接口共享成为可能,但它并不强制共享
    15     class UnsharedConcreteFlyweight : Flyweight
    16     {
    17         public override void Operation(int extrinsicstate)
    18         {
    19             Console.WriteLine($"不共享的具体Flyweight:{extrinsicstate}");
    20         }
    21     }
    22     //享元工厂,用来创建并管理Flyweight对象,它主要是用来确保合理的
    23     //共享Flyweight,当用户请求一个Flyweight时,享元工厂对象提供一个
    24     //已经创建的实例或者创建一个(如果不存在的话)
    25     class FlyweighFactory
    26     {
    27         private Hashtable flyweights = new Hashtable();
    28         /// <summary>
    29         /// 初始化工厂时,先生成三个实例
    30         /// </summary>
    31         public FlyweighFactory()
    32         {
    33             flyweights.Add("X", new ConcreteFlyweight());
    34             flyweights.Add("Y", new ConcreteFlyweight());
    35             flyweights.Add("Z", new ConcreteFlyweight());
    36         }
    37         //根据客户端请求,获得已生成的实例
    38         public Flyweight GetFlyweight(string key)
    39         {
    40             return ((Flyweight) flyweights[key]);
    41         }
    42     }

    客户端:

     1         public static void Main()
     2         {
     3             //代码外部状态
     4             int extrinsicstate = 22;
     5             FlyweighFactory f = new FlyweighFactory();
     6 
     7             Flyweight fx = f.GetFlyweight("X");
     8             fx.Operation(--extrinsicstate);
     9 
    10             Flyweight fy = f.GetFlyweight("Y");
    11             fy.Operation(--extrinsicstate);
    12 
    13             Flyweight fz = f.GetFlyweight("Z");
    14             fz.Operation(--extrinsicstate);
    15 
    16             UnsharedConcreteFlyweight uf = new UnsharedConcreteFlyweight();
    17 
    18             uf.Operation(--extrinsicstate);
    19 
    20             Console.ReadKey();
    21         }

    好,我们用享元模式将我们案例中的代码来重构一下:

     1     //网站抽象类
     2     abstract class WebSite
     3     {
     4         public abstract void Use();
     5     }
     6     //具体网站类
     7     class ConcreteWebSite : WebSite
     8     {
     9         private string name = "";
    10 
    11         public ConcreteWebSite(string name)
    12         {
    13             this.name = name;
    14         }
    15         public override void Use()
    16         {
    17             Console.WriteLine($"网站分类{name}");
    18         }
    19     }
    20     //网站工厂
    21     class WebSiteFactory
    22     {
    23         private Hashtable flyweights = new Hashtable();
    24 
    25         public WebSite GetWebSiteCategory(string key)
    26         {
    27             //判断是否存在这个对象,如果存在,则直接返回,否则实例化它再返回
    28             if (!flyweights.ContainsKey(key))
    29             {
    30                 flyweights.Add(key, new ConcreteWebSite(key));
    31                 return (WebSite)flyweights[key];
    32             }
    33             else
    34             {
    35                 return (WebSite)flyweights[key];
    36             }
    37         }
    38         //获得网站分类总数
    39         public int GetWebSiteCount()
    40         {
    41             return flyweights.Count;
    42         }
    43     }

    客户端:

     1         public static void Main()
     2         {
     3             WebSiteFactory f = new WebSiteFactory();
     4 
     5             //实例化 门户网站 对象
     6             WebSite fx = f.GetWebSiteCategory("门户网站");
     7             fx.Use();
     8 
     9             //共享上方生成的对象,不再实例化
    10             WebSite fy = f.GetWebSiteCategory("门户网站");
    11             fy.Use();
    12             //共享上方生成的对象,不再实例化
    13             WebSite fz = f.GetWebSiteCategory("门户网站");
    14             fz.Use();
    15 
    16             WebSite fl = f.GetWebSiteCategory("个人博客");
    17             fl.Use();
    18 
    19             WebSite fm = f.GetWebSiteCategory("个人博客");
    20             fm.Use();
    21 
    22             WebSite fn = f.GetWebSiteCategory("个人博客");
    23             fn.Use();
    24 
    25             //统计实例化个数,结果应该为2
    26             Console.WriteLine($"网站分类总数为{f.GetWebSiteCount()}");
    27             Console.ReadKey();
    28         }

    这样写基本体现了享元模式享元模式,但是我们在做项目的过程中,即便是再相似的项目,面对不同企业,也会有不同的地方。

    好,今天的享元模式就讲到这里了,下一篇我们讲 解释器模式


    本系列将持续更新,喜欢的小伙伴可以点一下关注和推荐,谢谢大家的支持

  • 相关阅读:
    李洪强经典面试题51-KVO-KVC
    李洪强经典面试题50-内存管理
    李洪强经典面试题49-Objective-C
    李洪强经典面试题48-C语言
    李洪强经典面试题47--UNIX常用命令
    李洪强经典面试题46-版本控制
    绿麻雀网贷系统通用注入分析
    跟着百度学PHP[5]函数篇2-PHP中的特殊形式的函数
    报错注入分析之(count()、rand()、group by)分析,被大佬称为floor报错注入
    跟着百度学PHP[5]函数篇1-参数
  • 原文地址:https://www.cnblogs.com/xiaomowang/p/6404913.html
Copyright © 2020-2023  润新知