一. 概述

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

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

例如一个字母“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. zookeeper特性与节点说明

    一.zookeeper概要.背景及作用 zookeeper产生背景: 项目从单体到分布式转变之后,将会产生多个节点之间协同的问题.如: 每天的定时任务由谁哪个节点来执行? RPC调用时的服务发现? 如 ...

  2. selenium自动化测试-浏览器基本操作

    webdriver 通过协议和接口发现DOM中的元素,并实现控制浏览器的行为,例如打开浏览器.控制浏览器大小. 浏览器刷新及浏览器前进.后退等,接下来介绍浏览器的一些基本操作. 1.启动浏览器 dri ...

  3. [Week 2][Guarantee of PLA] the Correctness Verification of PLA

    Conditions: For the data set D, there exists a $\displaystyle W_{f}$ which satisfies that for every ...

  4. .net core 3.0 Signalr - 08 业务实现-客户端demo

    由于signalr作为一个单独的推送系统,跟业务系统是分离开的,所以此处模拟一个业务系统,新建一个.net core app项目 ## 模拟实现一个登录功能 我们的登录很简单,当进入系统,如果检测到用 ...

  5. 设计时数据源:在PostgreSql 数据查询中使用参数过滤

    在上一篇文章中,我们学习了如何设计时连接PostgreSQL 数据库及环境搭建.本节我们来学习使用PostgreSql 数据源时,创建数据集时带参数过滤的查询语句写法. 在报表中包含两种参数,可参考博 ...

  6. css 精灵图的使用

    精灵图的使用 1.给一个容器定义一个大小(宽高) 2.引入背景图 3.定位到自己你想要的图片位置 例如:  background-position: 0 0;  background-position ...

  7. shell检测网站地址是否存活

    #!/bin/bash . /etc/init.d/functions url_list=(www.baidu.com) ChkCurl(){ i=0 while [ $i -lt 2 ] do cu ...

  8. typedef说明

    typedef 只对已有的类型进行别名定义,不产生新的类型: #define 只是在预处理过程对代码进行简单的替换. 类比理解: typedef  unsigned int  UINT32;  // ...

  9. XCTF-upload

    这道题的话,看了一下是RCTF-2015的原题....可是这也太难了吧QAQ,文件名作为注入点可也是太秀了,害的我一直以为是文件上传QAQ,并且这道题的坑还不少,就是注入时的输出只能为10进制.... ...

  10. vodevs3031 最富有的人

    在你的面前有n堆金子,你只能取走其中的两堆,且总价值为这两堆金子的xor值,你想成为最富有的人,你就要有所选择. 输入描述 Input Description 第一行包含两个正整数n,表示有n堆金子. ...