一. 概述

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

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

例如一个字母“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. 它的目的是大幅度地减少需要实例化的类的数量

设计模式C++描述----12.享元(Flyweight)模式的更多相关文章

  1. Java 实现享元(Flyweight)模式

    /** * 字母 * @author stone * */ public class Letter { private String name; public Letter(String name) ...

  2. 十二、享元(Flyweight)模式--结构模式(Structural Pattern)

    Flyweight在拳击比赛中指最轻量级,即"蝇量级",有些作者翻译为"羽量级".这里使用"享元 模式"更能反映模式的用意. 享元模式以共享 ...

  3. 设计模式的征途—12.享元(Flyweight)模式

    现在在大力推行节约型社会,“浪费可耻,节俭光荣”.在软件系统中,有时候也会存在资源浪费的情况,例如,在计算机内存中存储了多个完全相同或者非常相似的对象,如果这些对象的数量太多将导致系统运行代价过高.那 ...

  4. python 设计模式之享元(Flyweight)模式

    #写在前面 这个设计模式理解起来很容易.百度百科上说的有点绕口. #享元模式的定义 运用共享技术来有効地支持大量细粒度对象的复用. 它通过共享已经存在的对橡大幅度减少需要创建的对象数量.避免大量相似类 ...

  5. 享元(FlyWeight)模式

    享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能.这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式.享元模式尝试 ...

  6. 十一、结构模式之享元(Flyweight)模式

    什么是享元模式 享元模式是对象的结构模式,是运用共享技术来有效的支持大量细粒度的对象.享元对象能做到共享的关键是区分内蕴状态和外蕴状态.一个内蕴状态是存储在享元对象内部,并且是不会随环境改变而有所不同 ...

  7. 设计模式(十)享元模式Flyweight(结构型)

    设计模式(十)享元模式Flyweight(结构型) 说明: 相对于其它模式,Flyweight模式在PHP实现似乎没有太大的意义,因为PHP的生命周期就在一个请求,请求执行完了,php占用的资源都被释 ...

  8. Java设计模式(十一) 享元模式

    原创文章,同步发自作者个人博客 http://www.jasongj.com/design_pattern/flyweight/.转载请注明出处 享元模式介绍 享元模式适用场景 面向对象技术可以很好的 ...

  9. C#设计模式(12)——享元模式(Flyweight Pattern)

    一.引言 在软件开发过程,如果我们需要重复使用某个对象的时候,如果我们重复地使用new创建这个对象的话,这样我们在内存就需要多次地去申请内存空间了,这样可能会出现内存使用越来越多的情况,这样的问题是非 ...

随机推荐

  1. Flask基础(14)-->自定义过滤器

    Flask基础(13)-->自定义过滤器 什么是过滤器? 过滤器的本质就是函数.有时候我们不仅仅只是需要输出变量的值,我们还需要修改变量的显示,甚至格式化.运算等等,而在模板中是不能直接调用 P ...

  2. 【ADO.NET基础知识】SqlConnection、command、DataSet 、DataTable、dataAdapter

    1.使用Connection连接数据库的步骤: (1).添加命名空间 System.Data.SqlClient(注意:初学者经常会忘记) (2)定义连接字符串.连接SQL Server 数据库时: ...

  3. Python采集VIP收费QQ音乐,一起来听周董最新的《说好不哭》,省3块不香吗?

    环境: windows python3.6.5 模块: requests selenium json re urllib 环境与模块介绍完毕后,就可以来实行我们的操作了. 第1步: 通过一个解析网站: ...

  4. JAVA 8 新特性Stream初体验

    什么是 Stream? Stream(流)是一个来自数据源的元素队列并支持聚合操作 <strong元素队列< strong="">元素是特定类型的对象,形成一个队 ...

  5. Spring IOC(1)----容器刷新(refresh())之前

    首先本次分析是基于注解形式的,想来xml格式的原理都是类似的. 首先说一下什么是Bean定义(beandefinition):bean定义并不是实例化的bean,而是bean对象的一些信息,根据这些定 ...

  6. XCTF-CAT

    果然还是我太菜了呜呜呜,这道题仍然是没有自己做出来.哎. 这一道用的并不是PHP的环境,而是用Python中的Django编写的. 记得做过类似的一道题目.来源于MOCTF中的网站扫描器,当时做完后其 ...

  7. Faith 信念

    Today I’d like to talk about faith. With faith, you’ll go further and never be lost. Faith is free a ...

  8. Python的字符串编码

    本文用实验详细地演示了Python2和Python3在字符串编码上的区别. 在Python2中,字符串字面量对应于8位的字符或面向字节编码的字节字面量.这些字符串的一个重要限制是它们无法完全地支持国际 ...

  9. PHP array_reverse

    1.函数的作用:将数组中的元素顺序反转 2.函数的参数: @params array $array 需要反转顺序的数组 @params $preversed_key  数值索引是否保持不变,非数值索引 ...

  10. [BZOJ1116] CLO

    1116: [POI2008]CLO Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1311  Solved: 709[Submit][Status] ...