一. 概述

在面向对象系统的设计何实现中,创建对象是最为常见的操作。

这里面就有一个问题:如果一个应用程序使用了太多的对象,就会造成很大的存储开销。特别是对于大量轻量级(细粒度)的对象,比如在文档编辑器的设计过程中,我们如果没有为字母创建一个对象的话,系统可能会因为大量的对象而造成存储开销的浪费。

例如一个字母“a”在文档中出现了100000次,而实际上我们可以让这一万个字母“a”共享一个对象,当然因为在不同的位置可能字母“a”有不同的显示效果(例如字体和大小等设置不同),在这种情况我们可以为将对象的状态分为“外部状态”和“内部状态”,将可以被共享(不会变化)的状态作为内部状态存储在对象中,而外部对象(例如上面提到的字体、大小等)我们可以在适当的时候将外部对象最为参数传递给对象(例如在显示的时候,将字体、大小等信息传递给对象)。

二. 享元模式

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

结构图如下:

Flyweight:所有具体享元类的父类,或接口

ConcreteFlyweight:具体享元类,实现具体的操作

UnshareConcreteFlyweight:不需要共享的子类

FlyweightFactory:合理的创建并管理享元类

代码如下:

  1. //享元类
  2. class Flyweight
  3. {
  4. public:
  5. virtual ~Flyweight() {}
  6. virtual void Operation(const string& extrinsicState) {}
  7. string GetIntrinsicState()
  8. {
  9. return this->_intrinsicState;
  10. }
  11. protected:
  12. Flyweight(string intrinsicState)
  13. {
  14. this->_intrinsicState = intrinsicState;
  15. }
  16. private:
  17. string _intrinsicState;
  18. };
  19. //具体享元类
  20. class ConcreteFlyweight:public Flyweight
  21. {
  22. public:
  23. ConcreteFlyweight(string intrinsicState):Flyweight(intrinsicState)
  24. {
  25. cout<<"ConcreteFlyweight Build....."<<intrinsicState<<endl;
  26. }
  27. ~ConcreteFlyweight() {}
  28. //实现接口
  29. void Operation(const string& extrinsicState)
  30. {
  31. cout<<"内部["<<this->GetIntrinsicState()<<"] 外部["<<extrinsicState<<"]"<<endl;
  32. }
  33. };
  34. //享元工厂
  35. class FlyweightFactory
  36. {
  37. public:
  38. FlyweightFactory() {}
  39. ~FlyweightFactory() {}
  40. //确保合理的共享 Flyweight
  41. Flyweight* GetFlyweight(const string& key)
  42. {
  43. vector<Flyweight*>::iterator it = _fly.begin();
  44. for (; it != _fly.end();it++)
  45. {
  46. if ((*it)->GetIntrinsicState() == key)
  47. {
  48. cout<<"already created by users...."<<endl;
  49. return *it;
  50. }
  51. }
  52. Flyweight* fn = new ConcreteFlyweight(key);
  53. _fly.push_back(fn);
  54. return fn;
  55. }
  56. private:
  57. vector<Flyweight*> _fly;
  58. };
  59. //测试
  60. int main(int argc,char* argv[])
  61. {
  62. FlyweightFactory* fc = new FlyweightFactory();
  63. //不同的对象,享元工厂将会创建新的享元类
  64. Flyweight* fw1 = fc->GetFlyweight("Object A");
  65. Flyweight* fw2 = fc->GetFlyweight("Object B");
  66. //相同的对象,享元工厂将会使用一个已创建的享元类
  67. Flyweight* fw3 = fc->GetFlyweight("Object A");
  68. return 0;
  69. }

三. 说明

1. 享元工厂类是重点,因为它创建并管理享元对象,对没有的对象它会创建,对已有的对象它会提供一个已创建的实例。

2. 可以想像有一个对象池,里面都是一些享元类,享元工厂的作用就是从对象池里取对象。

3. 它的目的是大幅度地减少需要实例化的类的数量

最新文章

  1. 看完这篇让你对各种前端build工具不再懵逼!
  2. 决策树的python实现
  3. Qt设计器中设置border-image注意问题
  4. [游戏学习24] MFC 各种绘图 字体学习
  5. JavaScript中的3种弹出式消息提醒(警告窗口,确认窗口,信息输入窗口)的命令是什么?
  6. Ubuntu 下 Neo4j单机安装和集群环境安装
  7. oracle-12c-rac 报:ORA-01078
  8. 写 一个PHP脚本遇到的问题总结
  9. 数据结构(树链剖分,堆):HNOI 2016 network
  10. USACO6.4-The Primes
  11. LeetCode_Maximal Rectangle
  12. 【转载】stm32的GPIO八种工作模式
  13. OC中自定义构造方法
  14. (转)Linux系统安装时分区的选择
  15. NOIP2014-3-15模拟赛
  16. 45个值得收藏的 CSS 形状
  17. spring redis 注解实现缓存机制
  18. Linux系统基础5周入门精讲(服务器介绍)
  19. 转录组的组装Stingtie和Cufflinks
  20. Java基础之疑难知识点

热门文章

  1. json与java对象的转换,以及struts2对json的支持,实现ajax技术
  2. SUSE Storage6 环境搭建详细步骤 - Win10 + VMware WorkStation
  3. flask+阿里云短信服务实现注册发送手机验证码
  4. Zookeeper工作过程详解
  5. 加密解密 之base系列编码
  6. 重载operator new delete函数
  7. badboy录制脚本
  8. 朋友外包干了5年java,居然不知道dubbo-monitor是怎么用的?
  9. 渗透测试-基于白名单执行payload--Compiler
  10. powershell下ssh客户端套件实现