设计模式(二十二)享元模式

享元模式(Flyweight),运用共享技术有效地支持大量细粒度的对象。享元模式可以避免大量非常相似类的开销。在程序设计中,有时需要生成大量细粒度的类实例来表示数据。如果能发现这些实例除了几个参数外基本都是相同的,有时就能够受大幅度地减少需要实例化的类的数量。如果能把那些参数移到类实例的外面,在方法调用时将它们传递进来,就可以通过共享大幅度地减少单个实例的数目。

应用场景

1、如果一个应用程序使用了大量的对象,而大量的这些对象造成了很大的存储开销是就应该考虑使用;

2、对象的大多数状态可以外部状态,如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象,此时可以考虑使用享元模式。

实际上在.NET中的字符串 string 就是运用 Flyweight 模式。

基本代码

 1 // Flyweight 类是所有具体享元类的超类或接口,通过这个接口,Flyweight 可以接受并作用于外部状态
 2 abstract class Flyweight
 3 {
 4   // 
 5   public abstract void Operation(int extrinsicstate);
 6 }
 7 
 8 // ConcreteFlyweight 是继承 Flyweight 超类或实现 Flyweight 接口,并未内部状态增加存储空间
 9 class ConcreteFlyweight : Flyweight
10 {
11   public override void Operation(int extrinsicstate);
12   {
13     Console.WriteLine("具体 Flyweight:" + extrinsicstate);
14   }
15 }
16 
17 // UnsharedConcreteFlyweight 是指那些不需要共享的 Flyweight 子类。
18 class UnsharedConcreteFlyweight : Flyweight
19 {
20   public override void Operation(int extrinsicstate);
21   {
22     Console.WriteLine("不共享的具体 Flyweight:" + extrinsicstate);
23   }
24 }
25 
26 // FlyweightFactory 是一个享元工厂,用来创建并管理 Flyweight 对象。它主要是用来确保合理地共享 Flyweight , 当用户请求一个 Flyweight 时,
27 // FlyweightFactory 对象提供一个已创建的实例或者创建一个(如果不存在的话)。
28 class FlyweightFactory
29 {
30   private Hashtable flyweights = new Hashtable();
31 
32   public FlyweightFactory()
33   {
34     flyweights.Add("X", new ConcreteFlyweight());
35     flyweights.Add("Y", new ConcreteFlyweight());
36     flyweights.Add("Z", new ConcreteFlyweight());
37   }
38 
39   // 根据客户端请求,获得已生成的实例
40   public Flyweight GetFlyweight(string key)
41   {
42     return ((Flyweight)flyweights[key]);
43   }
44 }
45 
46 // 客户端
47 static void Main(string[] args)
48 {
49   // 代码外部状态
50   int extrinsicstate = 22;
51 
52   FlyweightFactory f = new FlyweightFactory();
53 
54   Flyweight fx = f.GetFlyweight("X");
55   fx.Operation(--extrinsicstate);
56 
57   Flyweight fy = f.GetFlyweight("Y");
58   fy.Operation(--extrinsicstate);
59 
60   Flyweight fz = f.GetFlyweight("Z");
61   fz.Operation(--extrinsicstate);
62 
63   UnsharedConcreteFlyweight uf = new UnsharedConcreteFlyweight();
64   uf.Operation(--extrinsicstate);
65 
66   Console.Read();
67 }

【例】网站共享代码

基本代码

 1 // 用户类
 2 public class User
 3 {
 4   private string name;
 5   public User(string name)
 6   {
 7     this.name = name;
 8   }
 9 
10   public string Name
11   {
12     get { return name; }
13   }
14 }
15 
16 // 网站抽象类
17 abstract class Website
18 {
19   // Use 方法需要传递 User 对象
20   public abstract void Use(User user);
21 }
22 
23 // 具体网站类
24 class ConcreteWebSite : Website
25 {
26   private string name = " ";
27   public ConcreteWebSite(string name)
28   {
29     this.name = name;
30   }
31   public override void Use(User user)
32   {
33     Console.WriteLine("网站分类:" + name + “用户:” + user.Name);
34   }
35 }
36 
37 //  网站工厂类
38 class WebSiteFacory
39 {
40   private Hashtable flyweights = new Hashtable();
41 
42   // 获得网站分类
43   public WebSite GetWebSiteCategory(string key)
44   {
45     // 判断是否存在这个对象,如果存在,则直接返回,若不存在,则实例化后再返回
46     if(!flyweights.ContainsKey(key))
47       flyweights.Add(key, new ConcreteWebSite(key));
48     return ((WebSite)flyweights[key]);
49   }
50 
51   // 获得网站分类总数,得到实例的个数
52   public int GetWebSiteCount()
53   {
54     return flyweights.Count;
55   }
56 }
57 
58 // 客户端
59 static void Main(string[] args)
60 {
61   WebSiteFactory f = new WebSiteFactory();
62 
63   WebSite fx = f.GetWebSiteCategory("产品展示");
64   fx.Use(new User("1"));
65 
66   WebSite fy = f.GetWebSiteCategory("产品展示");
67   fy.Use(new User("2"));
68 
69   WebSite fz = f.GetWebSiteCategory("产品展示");
70   fz.Use(new User("3"));
71 
72   WebSite fl = f.GetWebSiteCategory("博客");
73   fl.Use(new User("4"));
74 
75   WebSite fm = f.GetWebSiteCategory("博客");
76   fm.Use(new User("5"));
77 
78   WebSite fn = f.GetWebSiteCategory("博客");
79   fn.Use(new User("6"));
80 
81   Console.WriteLine("网站分类总数为:{0}", f.GetWebSiteCount);
82 
83   Console.Read();
84 }

 

posted @ 2015-06-21 21:34  壬子木  阅读(120)  评论(0)    收藏  举报