享元模式(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         }

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

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


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

posted @ 2017-02-16 17:35  萌萌丶小魔王  阅读(273)  评论(0编辑  收藏  举报