FlyWeight模式——设计模式学习笔记

FlyWeight模式

一 意图

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

二 动机

      有些应用程序得益于在其整个设计过程中采用对象技术,但简单化的实现代价极大。

使用面向对象的抽象化,可能会造成庞大的对象群,造成空间的巨大消耗,而影响性能。

在文档编辑器例子中如果一个字符对应一个对象,那么一篇文档所要容纳的对象将是非常的庞大耗费大量的内存。

  而实际组成文档的字符是有限的,是由这些字符不同的组合和排列得到的。

所以需要共享,将基本的字符进行共享,将使得字符对象变得有限。

Flyweight只存储相应的字符代码

这里的关键概念是内部状态外部状态之间的区别。

  内部状态存储于flyweight中,它包含了独立于flyweight场景的信息,这些信息使得flyweight可以被共享。

如字符代码,字符大小……

  外部状态取决于flyweight场景,并根据场景而变化,因此不可共享。用户对象负责在必要的时候将外部状态传递给flyweight。

如字符位置,字符颜色……


三 适用性及其结构

当以下情况都成立时使用Flyweight模式:

•一个应用程序使用了大量的对象。

• 完全由于使用大量的对象,造成很大的存储开销。

• 对象的大多数状态都可变为外部状态。

• 如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象。

• 应用程序不依赖于对象标识。由于Flyweight对象可以被共享,对于概念上明显有别的对象,标识测试将返回真值。

结构:


description:

•Flyweight

— 描述一个接口,通过这个接口Flyweight可以接受并作用于外部状态。

• ConcreteFlyweight

— 实现Flyweight接口, 并为内部状态( 如果有的话) 增加存储空间。

ConcreteFlyweight对象必须是可共享的。它所存储的状态必须是内部的;即,它必

须独立于Concrete Flyweight对象的场景。

• UnsharedConcreteFlyweight

— 并非所有的Flyweight子类都需要被共享。Flyweight接口使共享成为可能,但它并不强制共享。在Flyweight对象结构的某些层次, UnsharedConcreteFlyweight对象通常

将ConcreteFlyweight对象作为子节点(Row和Conum就是这样)。

• FlyweightFactory

— 创建并管理Flyweight对象。

— 确保合理地共享Flyweight。当用户请求一个Flyweight时,FlyweightFactory对象提供一个已创建的实例或者创建一个(如果不存在的话)。

• Client

— 维持一个对Flyweight的引用。

— 计算或存储一个(多个)Flyweight的外部状态。

 

Analysis:

  Flyweight执行时所需的状态必定是内部的或外部的。内部状态存储于ConcreteFlyweight对象之中;

而外部对象则由C l i e n t对象存储或计算。当用户调用Flyweight对象的操作时,将该状态传递给它。

• 用户不应直接对ConcreteFlyweight类进行实例化,而只能从FlyweightFactory对象得到ConcreteFlyweight对象,

  这可以保证对它们适当地进行共享。

存储节约由以下几个因素决定:

• 因为共享,实例总数减少的数目

• 对象内部状态的平均数目

• 外部状态是计算的还是存储的

 

四 代码实现

Note:

删除外部状态:该模式的可用性在很大程度上取决于是否容易识别外部状态并将它从

共享对象中删除

管理共享对象:引用计数和垃圾回收……

Example :象棋中的棋局中的棋子,任何棋局都是32个 棋子的不同组合。

1 Flyweight

Chess提供了外部状态的设置

复制代码
/*----------------------------------------------------------------*/
/* class Object */
/*----------------------------------------------------------------*/
class Object
{

};

/*----------------------------------------------------------------*/
/* class Chess */
/*----------------------------------------------------------------*/
class Chess: public Object
{
public:
Chess(){}
void setShape(int shape){}
void setSize(int size){}
void setHeight(int height){}
void setPos(int pos){}
virtual void draw()
{
cout<<"Chess draw"<<endl;
}
private:
int m_shape;
int m_size;
int m_height;
int m_pos;
};
复制代码

 

CChess保存内部状态

复制代码
/*----------------------------------------------------------------*/
/* class CChess */
/*----------------------------------------------------------------*/
class CChess: public Chess
{
public:
CChess(int code)
{
m_code = code;
}
virtual void draw()
{
cout<<"CChess draw"<<endl;
}
private:
int m_code;
};
复制代码


ChessFactory提供创建享元CChess的接口

复制代码
/*----------------------------------------------------------------*/
/* class ChessFactory */
/*----------------------------------------------------------------*/
class ChessFactory: public Object
{
#define CHECSS_MAX_NUM (16)
#define CHESS_CODE_OFFSET (0x1000)
class ChessCodeMap
{
public:
int m_code;
CChess* m_chess;
};
public:
ChessFactory()
{
for (int i = 0; i < CHECSS_MAX_NUM; i++)
{
m_chessMap[i].m_chess = NULL;
m_chessMap[i].m_code = i;
}
}
CChess* createChess(int code)
{
for (int i = 0; i < CHECSS_MAX_NUM; i++)
{
if (m_chessMap[i].m_code == code)
{
if (m_chessMap[i].m_chess == NULL)
{
m_chessMap[i].m_chess = new CChess(code);
}

return m_chessMap[i].m_chess;
}
}

return NULL;
}
private:
ChessCodeMap m_chessMap[CHECSS_MAX_NUM];
};
复制代码


Test

 

复制代码
#include "flyweight.h"

int main()
{
ChessFactory* chessFc = new ChessFactory();
CChess* chess = chessFc->createChess(1);
chess->draw();

return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!
提供的源码资源涵盖了小程序应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值