022 --- 第26章 享元模式
简述:
享元模式:运用共享技术有效地支持大量细粒度的对象。
享元模式包括:享元工厂类、享元接口类、具体享元类
享元工厂类: 用来创建并管理享元接口类对象,它主要是用来确保合理地共享享元接口类,当用户请求一个享元接口类对象时,享元工厂类对象提供一个已创建的实例或者创建一个(不存在的话)
享元接口类:所有具体享元类的超类或接口,通过这个接口可以接受并作用于外部状态。
具体享元类:继承享元接口超累或实现享元接口类接口,并为内部状态增加存储空间
不共享具体享元类:指那些不需要共享的享元接口类的子类,因为享元接口类共享成为可能,但它并不强制共享。
应用场景:如果一个应用程序使用了大量的对象,而大量的这些对象造成了很大的存储开销时,就应该考虑使用;还有就是对象大多数状态可以是外部状态,如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象,此时可以考虑使用享元模式
注:开发环境调整为VS2017,操作系统win11
享元模式:
1 #include <iostream> 2 #include <map> 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 <iostream> 2 #include <map> 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 }
输出结果: