享元模式的主要目的、意图是为对象的大量使用提供一种共享机制。该模式的思想重在复用、共享复用。像文字、列表中的格子等这类多数都是需要考虑复用技术,否则必将大量耗费内存空间而使资源以及性能等大量耗费。该模式的类关系图参考如下:

模式的编码结构参考如下:

 namespace flyweight
{
class Flyweight {};
class ConcreteFlyweight : public Flyweight {};
class UnsharedFlyweight : public Flyweight {};
class FlyweightFactory
{
public:
typedef int TKey;
Flyweight* getFlyweight(const TKey& key) {
auto pRetItem = this->getItemByKey(key);
if (nullptr == pRetItem) {
pRetItem = this->createNewInstance(key);
if (nullptr != pRetItem) {
this->addNewItem(pRetItem);
}
}
return pRetItem;
} private:
Flyweight* getItemByKey(const TKey& key) {
// some code here........
return nullptr;
} Flyweight* createNewInstance(const TKey& key) {
// some code here........
return nullptr;
} void addNewItem(Flyweight* pNewItem) {
// some code here........
} };//class FlyweightFactory }//namespace flyweight

Flyweight编码结构参考

关于复用、共享技术,多数情况下我们也会使用Cache,或者使用空闲队列等用以暂时存放当前不正在被使用的那些“垃圾”对象。待下次有需要时,再从中取出来使用。如:列表UI的格子,当格子移出可视框区域后,我们不会立即将它们删除掉,而是移入空闲队列,另一端因为空出一片“空地”,于是需要一个或几个新的格子来填补该区域,此时就从空闲队列中取出可用的,如果取不到,此时才去新创建出格子实例。还有像游戏AI中的许多对象也是如此。

再如像文字引擎或图形渲染库等,一个文字或一张图像的纹理在引擎中可能就只有一份轮廓、图像实例,而在渲染时,由外部指定相关参数,如:位置,混合颜色、系数、缩放比例等,将这份实例对象,渲染展现到各个位置上,从而实现资源的共享使用。如不这样,则内存资源的使用将耗费极大(因为图像是相当耗资源的)。

在前面【结构型】AbstractFactory模式 & FactoryMethod模式中,也曾提到过,我们可以通过一些技术手段,实现通用的带Cache的通用工厂,从而达到资源的复有目的。

Cache技术与享元模式的探讨:

1) Cache注重的是复用,重复利用。说白了,被复用的对象,在被重新使用时,也仅供1个使用者使用,并未达到共享、共用的目的。

2) 享元更注重共享使用,即:对某对象共享使用,一个对象,可以供N个使用者使用。或许形象点比喻,可理解为:一个对象实例,然后有着一个使用它的引用计数器一样对其进行使用计数。有N个对象使用它时,它的记数就是n。当都没有被时,这时,它才有可能被从内存中移除。此时这边就有个疑问:既然N个使用者在使用同一个对象,那这对象的数据不乱套了么?是的,也正是因为此,在使用享元模式设计对象时,必需要对Flyweight对象的数据属性进行区别,将公共的数据由模式内部维护,而特性数据,只能由使用者自己维护、提供。因此,这N个使用者,在使用共享对象时,所进行的操作,都只会影响他们自己持有的特性数据属性。这点很关键,也是难点。

3) 享元模式在设计上,也并非说所提供的对象一定都必需是要共享的,它也可以提供不共享的对象。极端情况下,所提供的对象,全都是不共享的,然后再支持对象回收机制,此时,其实就退化成前面说的Cache了。

【结构型】Flyweight模式的更多相关文章

  1. JAVA设计模式(09):结构型-代理模式(Proxy)

    代理模式是经常使用的结构型设计模式之中的一个,当无法直接訪问某个对象或訪问某个对象存在困难时能够通过一个代理对象来间接訪问,为了保证client使用的透明性,所訪问的真实对象与代理对象须要实现同样的接 ...

  2. 结构型--代理模式(Proxy)

    一.代理模式是什么? 代理模式属于GOF23设计模式中结构型中的设计模式,通过代理对象来屏蔽(部分或者屏蔽)对真实对象的直接访问,下图为UML图: 在代理模式中组件包括:抽象角色接口.代理角色类.真实 ...

  3. 结构型---组合模式(Composite Pattern)

    组合模式的定义 组合模式允许你将对象组合成树形结构来表现”部分-整体“的层次结构,使得客户以一致的方式处理单个对象以及对象的组合. 组合模式实现的最关键的地方是——简单对象和复合对象必须实现相同的接口 ...

  4. 结构型---外观模式(Facade Pattern)

    定义 外观模式提供了一个统一的接口,用来访问子系统中的一群接口.外观定义了一个高层接口,让子系统更容易使用.使用外观模式时,我们创建了一个统一的类,用来包装子系统中一个或多个复杂的类,客户端可以直接通 ...

  5. 结构型---桥接模式(Bridge Pattern)

    定义 桥接模式即将抽象部分与实现部分脱耦,使它们可以独立变化.桥接模式的目的就是使两者分离,根据面向对象的封装变化的原则,我们可以把实现部分的变化封装到另外一个类中,这样的一个思路也就是桥接模式的实现 ...

  6. 结构型---代理模式(Proxy Pattern)

    代理模式的详细介绍 代理模式按照使用目的可以分为以下几种: 远程(Remote)代理:为一个位于不同的地址空间的对象提供一个局域代表对象.这个不同的地址空间可以是本电脑中,也可以在另一台电脑中.最典型 ...

  7. 设计模式之美:Structural Patterns(结构型模式)

    结构型模式涉及到如何组合类和对象以获得更大的结构. 结构型类模式采用继承机制来组合接口实现. 结构型对象模式不是对接口和实现进行组合,而是描述了如何对一些对象进行组合,从而实现新功能的一些方法. 因为 ...

  8. C#设计模式之十三代理模式(Proxy)【结构型】

    一.引言   今天我们要讲[结构型]设计模式的第七个模式,也是"结构型"设计模式中的最后一个模式,该模式是[代理模式],英文名称是:Proxy Pattern.还是老套路,先从名字 ...

  9. C#设计模式之十二代理模式(Proxy Pattern)【结构型】

    一.引言 今天我们要讲[结构型]设计模式的第七个模式,也是“结构型”设计模式中的最后一个模式,该模式是[代理模式],英文名称是:Proxy Pattern.还是老套路,先从名字上来看看.“代理”可以理 ...

  10. 结构型模式(七) 代理模式(Proxy)

    一.动机(Motivate) 在面向对象系统中,有些对象由于某种原因(比如对象创建的开销很大,或者某些操作需要安全控制,或者需要进程外的访问等),直接访问会给使用者.或者系统结构带来很多麻烦.如何在不 ...

随机推荐

  1. Extjs4 自定义组件

    Ext.onReady (function () { Ext.define ('MydesktopIcon', { /* Begin Definitions */ alias: 'widget.des ...

  2. didEndEditingRowAtIndexPath with nil indexPath

    在UITableViewController中,通过滑动删除按钮删除一行,首先收到Table view data source call: tableView:commitEditingStyle:f ...

  3. BestCoder Round #49

    呵呵哒,1001的dfs返回值写错,wa了两发就没分了,1002显然是PAM可是我没学过啊!!!压位暴力可不可以...看看范围貌似不行,弃疗...1003根本不会做,1004想了想lcc发现不可做,那 ...

  4. 舶来品P2P理财 能否成为“好声音”式好生意? 转

    华股财经 2012年11月29日 10:20:02 来源:互联网 字号:T|T   文/本刊记者 王奇 有数据显示,目前国内已有2000余家P2P公司,2007年至2011年上半年,其整体融资规模由2 ...

  5. LoadRunner基础入门教程

    原文地址:http://jingyan.baidu.com/article/215817f7dedfb01eda1423df.html 从LoadRunner英语字面上进行理解就是负载跑步者,为什么这 ...

  6. centOS 6.4挂载centOS分区

    今天想用centOS打开在windows下编辑的emacs笔记,发现好像不可以自动挂载nfts分区,搜了一下,发现一大坨,还是发个文来标记下好: 首先,安装rpmforge软件库的源 命令行下输入下面 ...

  7. hyperVisors

    容器有效地将由单个操作系统管理的资源划分到孤立的组中,以更好地在孤立的组之间平衡有冲突的资源使用需求 期望继续进军中国市场 就像IBM公司,惠普公司和戴尔公司在中国服务器市场的霸主地位一样,Inspu ...

  8. linux/hpux 添加用户

    #添加用户组, 组名dev, 组id为1001groupadd -g 1001 dev #添加用户组dev,不指定组idgroupadd dev #添加用户user1, id为111, 属于dev组, ...

  9. HDU 2485 Destroying the bus stations (IDA*+ BFS)

    传送门:http://acm.hdu.edu.cn/showproblem.php?pid=2485 题意:给你n个点,m条相连的边,问你最少去掉几个点使从1到n最小路径>=k,其中不能去掉1, ...

  10. Robotium API -- 判断测试结果的方法assert、is、search

    下面的这些方法都主要用来判断测试结果是否与预期结果相符,一般把is和search方法放在assert里面判断.assert最常用的还是assertThat方法,是Junit的判断,这里就不多说了. 断 ...