022 --- 第26章 享元模式


简述:

  享元模式:运用共享技术有效地支持大量细粒度的对象。

  享元模式包括:享元工厂类、享元接口类、具体享元类

    享元工厂类: 用来创建并管理享元接口类对象,它主要是用来确保合理地共享享元接口类,当用户请求一个享元接口类对象时,享元工厂类对象提供一个已创建的实例或者创建一个(不存在的话)

    享元接口类:所有具体享元类的超类或接口,通过这个接口可以接受并作用于外部状态。

    具体享元类:继承享元接口超累或实现享元接口类接口,并为内部状态增加存储空间

    不共享具体享元类:指那些不需要共享的享元接口类的子类,因为享元接口类共享成为可能,但它并不强制共享。

应用场景:如果一个应用程序使用了大量的对象,而大量的这些对象造成了很大的存储开销时,就应该考虑使用;还有就是对象大多数状态可以是外部状态,如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象,此时可以考虑使用享元模式

注:开发环境调整为VS2017,操作系统win11

享元模式:

 1 #include 
 2 #include 
 3 #include <string>
 4 using namespace std;
 5 
 6 // 享元接口类
 7 class CFlyweight
 8 {
 9 public:
10     virtual void Operation(int nExtrinsicstate) = 0;
11 };
12 
13 // 具体享元类
14 class CConcreteFlyweight : public CFlyweight
15 {
16 public:
17     virtual void Operation(int nExtrinsicstate) { cout << "具体Flyweight:" << nExtrinsicstate << endl; }
18 };
19 
20 // 不需要共享的享元子类
21 class CUnsharedConcreteFlyWeight : public CFlyweight
22 {
23 public:
24     virtual void Operation(int nExtrinsicstate) { cout << "不共享的具体Flyweight:" << nExtrinsicstate << endl; }
25 };
26 
27 // 享元工厂类
28 class CFlyweightFactory
29 {
30 private:
31     map<string, CFlyweight*> m_mapFlyweights;
32 
33 public:
34     CFlyweightFactory()
35     {
36         m_mapFlyweights.insert(make_pair("X", new CConcreteFlyweight()));
37         m_mapFlyweights.insert(make_pair("Y", new CConcreteFlyweight()));
38         m_mapFlyweights.insert(make_pair("Z", new CConcreteFlyweight()));
39     }
40 
41     ~CFlyweightFactory()
42     {
43         map<string, CFlyweight*>::iterator ite = m_mapFlyweights.begin();
44         while (ite != m_mapFlyweights.end())
45         {
46             if((*ite).second)
47             {
48                 delete (*ite).second;
49                 (*ite).second = NULL;
50             }
51                 
52             ++ite;
53         }
54 
55         m_mapFlyweights.clear();
56     }
57 
58     CFlyweight* GetFlyweight(string szKey) { return m_mapFlyweights[szKey]; }
59 };
60 
61 
62 int main()
63 {
64     int nExtrinsicstate = 22;
65 
66     CFlyweightFactory FlyweightFactory;
67 
68     CFlyweight* fx = FlyweightFactory.GetFlyweight("X");
69     fx->Operation(--nExtrinsicstate);
70 
71     CFlyweight* fy = FlyweightFactory.GetFlyweight("Y");
72     fy->Operation(--nExtrinsicstate);
73 
74     CFlyweight* fz = FlyweightFactory.GetFlyweight("Z");
75     fz->Operation(--nExtrinsicstate);
76 
77     CUnsharedConcreteFlyWeight uf;
78     uf.Operation(--nExtrinsicstate);
79 
80     system("pause");
81     return 0;
82 }

 输出结果:

例:网站共享代码

代码如下:

  1 #include 
  2 #include 
  3 #include <string>
  4 using namespace std;
  5 
  6 
  7 // 用户类
  8 class CUser
  9 {
 10 private:
 11     string m_szName;
 12 
 13 public:
 14     CUser(string szName) { m_szName = szName; }
 15 
 16     string GetName() { return m_szName; }
 17 };
 18 
 19 // 网站基类(享元接口类)
 20 class CWebSite
 21 {
 22 public:
 23     virtual void Use(CUser* pUser) = 0;
 24 };
 25 
 26 // 具体网站类(具体享元类)
 27 class CConcreteWebSite : public CWebSite
 28 {
 29 private:
 30     string m_szName;
 31 
 32 public:
 33     CConcreteWebSite(string szName) { m_szName = szName; }
 34 
 35     virtual void Use(CUser* pUser) { cout << "网站分类: " + m_szName << " 用户: " + pUser->GetName() << endl; }
 36 };
 37 
 38 // 网站工厂类(享元工厂类)
 39 class CWebSiteFactory
 40 {
 41 private:
 42     map<string, CWebSite*> m_mapWebSites;
 43 
 44 public:
 45     ~CWebSiteFactory()
 46     {
 47         map<string, CWebSite*>::iterator ite = m_mapWebSites.begin();
 48         while (ite != m_mapWebSites.end())
 49         {
 50             if ((*ite).second)
 51             {
 52                 delete (*ite).second;
 53                 (*ite).second = NULL;
 54             }
 55             ++ite;
 56         }
 57         m_mapWebSites.clear();
 58     }
 59 
 60     // 获得网站分类
 61     CWebSite* GetWebSiteCategory(string szKey)
 62     {
 63         if (!m_mapWebSites[szKey])
 64             m_mapWebSites[szKey] = new CConcreteWebSite(szKey);
 65 
 66         return m_mapWebSites[szKey];
 67     }
 68 
 69     // 获得网站分类总数
 70     int GetWebSiteCount() { return m_mapWebSites.size(); }
 71 };
 72 
 73 
 74 int main()
 75 {
 76     CWebSiteFactory WebSiteFactory;
 77 
 78     CWebSite* fx = WebSiteFactory.GetWebSiteCategory("产品展示");
 79     fx->Use(&CUser("GHL"));
 80 
 81     CWebSite* fy = WebSiteFactory.GetWebSiteCategory("产品展示");
 82     fy->Use(&CUser("GGG"));
 83 
 84     CWebSite* fz = WebSiteFactory.GetWebSiteCategory("产品展示");
 85     fz->Use(&CUser("HHH"));
 86 
 87     CWebSite* fl = WebSiteFactory.GetWebSiteCategory("博客");
 88     fl->Use(&CUser("LLL"));
 89 
 90     CWebSite* fm = WebSiteFactory.GetWebSiteCategory("博客");
 91     fm->Use(&CUser("ggg"));
 92 
 93     CWebSite* fn = WebSiteFactory.GetWebSiteCategory("博客");
 94     fn->Use(&CUser("hhh"));
 95 
 96     cout << "网站分类总数为: " << WebSiteFactory.GetWebSiteCount() << endl;
 97 
 98     system("pause");
 99     return 0;
100 }

 输出结果: