设计模式之享元模式(Flyweight)
享元模式顾名思义就是羽量级模式或者蝇级模式,形容体量小的应用,该模式主要的设计目的是为了迎合系统大量相似数据的应用而生,减少用于创建和操作相似的细碎对象所花费的成本。大量的对象会消耗高内存,享元模式给出了一个解决方案,即通过共享对象来减少内存负载。
作用
通过复用相同的对象来减少对象的创建数量,创建更小的对象组,并通过共享实现重用。通过归类,将对象的属性分为内蕴状态和外蕴状态。要创建具体的享元对象,我们需要创建一个享元工厂来统一管理对象的生成和输出,享元工厂是实现享元模式的关键。
举个例子,享元模式可以看成是一个工具箱,而享元对象就是工具箱内的具体的工具,我们在使用工具的时候,不必每回临时的制造工具,而是直接从工具箱里找到工具进行使用,这样就大大节约了制造工具的成本时间和工具占用的空间。
享元模式比较迷惑在于理解两种状态的分类,内蕴状态是对象本身的属性,在生成对象以后一般不会进行改变,比如工具中的属性:名字、大小、重量等,还有就是我们一般需要一个关键性的属性作为其区别于其他对象的key,如工具的话我们可以把名称作为找到工具的唯一标识。
外蕴状态是对象的外部描述,是每个对象的可变部分,比如对工具的使用地点、使用时间、使用人、工作内容的描述,这些属性不属于对象本身,而是根据每回使用情况进行变化的,这就需要制作成接口进行外部调用,而外蕴状态的维护是由调用者维护的,对象内不进行维护。
类视图

实现
//Flyweight
class tool
{
public:
//内蕴状态
string name;
int nSize;
int nWeight;
public:
//外蕴状态
virtual int used(string person, string work)=0;
}
//ConcreteFlyweight
class hammer : public tool
{
public:
hammer():name("hammer"){}
int used(string person, string work)
{
cout<< person <<"use"<<name<<"to" << work;
}
}
//ConcreteFlyweight
class screwdriver : public tool
{
screwdriver():name("screwdriver"){}
int used(string person, string work)
{
cout<< person <<"use"<< name << " to" << work;
}
}
//ConcreteFlyweight
class saw : public tool
{
saw():name("saw"){}
int used(string person, string work)
{
cout<< person <<"use"<< name <<"to" << work;
}
}
//FlyweightFactory
class toolbox
{
public:
toolbox();
virtual ~toolbox()
{
map<string,tool*>::iterator it = m_tool.find(toolname);
for(it=m_tool.begin();it!=m_tool.end();it++)
{
delete it.second;
}
}
tool* GetTool(string toolname)
{
map<string,tool*>::iterator it = m_tool.find(toolname);
if(it != m_tool.end())
{
return (tool*) it.second;
}
else
{
tool* tooltemp= NULL;
if(toolname == "hammer")
tooltemp = new hammer();
else if(toolname == "screwdriver")
tooltemp = new screwdriver();
else if(toolname == "saw")
tooltemp = new saw();
if(tooltemp !=NULL)
m_tool.insert(make_pair<string,tool*>(toolname,tooltemp));
return tooltemp;
}
}
private:
map<string,tool*> m_tool;
}
int main()
{
//外蕴状态 由调用者维护
string person1 = "zhangsan";
string person2 = "lisi";
string work1 = "make desk";
string work2 = "repair bike";
//生成工厂
toolbox tBox;
//获取享元
tool* tool1 = tBox.GetTool("hammer");
tool1.used(person1,work1);
tool* tool2 = tBox.GetTool("screwdriver");
tool2.used(person2,work2);
}
单享元(share)和复合享元(unshare)
复合享元也既是unshareFlyweight,其不再是单一的对象,而是一系列对象的组合,他们的关系由原来的一对一的关系,变成了一对多的关系。
举例说明,如【DP】中比较经典的围棋的例子,单享元模式下,我们对围棋的颜色种类进行共享,再棋盘的工厂类中只需包含黑白两颗棋子,就能完成对棋盘下棋的整个操作,而不用对每一个棋子进行操作。但是有一天需求增加了对胜负的要求,那么就需要对棋子的坐标进行记录,对于黑白两种颜色的棋子,相对应的就会有相同颜色棋子的坐标数组容器,like:map<string,vector<Point>> 这样的结构。
应用场景
- 需要创建大量对象时;
- 大多数对象可以分为内蕴和外蕴状态;
- 应用程序需要使用多种对象,并且重复使用;
设计模式之享元模式(Flyweight)的更多相关文章
- 乐在其中设计模式(C#) - 享元模式(Flyweight Pattern)
原文:乐在其中设计模式(C#) - 享元模式(Flyweight Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 享元模式(Flyweight Pattern) 作者:weba ...
- 设计模式-11享元模式(Flyweight Pattern)
1.模式动机 在面向对象程序设计过程中,有时会面临要创建大量相同或相似对象实例的问题.创建那么多的对象将会耗费很多的系统资源,它是系统性能提高的一个瓶颈. 享元模式就是把相同或相似对象的公共部分提取出 ...
- 二十四种设计模式:享元模式(Flyweight Pattern)
享元模式(Flyweight Pattern) 介绍运用共享技术有效地支持大量细粒度的对象. 示例有一个Message实体类,某些对象对它的操作有Insert()和Get()方法,现在要运用共享技术支 ...
- 设计模式之享元模式(Flyweight)摘录
23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于怎样创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...
- 【UE4 设计模式】享元模式 Flyweight Pattern
概述 描述 运用共享技术有效地支持大量细粒度对象的复用.系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用. 由于享元模式要求能够共享的对象必须是细粒度对象,因此它又称为轻 ...
- [设计模式] 11 享元模式 Flyweight
转 http://blog.csdn.net/wuzhekai1985/article/details/6670298 问题 在面向对象系统的设计何实现中,创建对象是最为常见的操作.这里面就有一个问题 ...
- 设计模式 笔记 享元模式 Flyweight
//---------------------------15/04/20---------------------------- //Flyweight 享元模式------对象结构型模式 /* 1 ...
- 【设计模式】—— 享元模式Flyweight
前言:[模式总览]——————————by xingoo 模式意图 享元模式,也叫[轻量级模式]或者[蝇量级模式].主要目的就是为了减少细粒度资源的消耗.比如,一个编辑器用到大量的字母数字和符号,但是 ...
- 结构型设计模式之享元模式(Flyweight)
结构 意图 运用共享技术有效地支持大量细粒度的对象. 适用性 一个应用程序使用了大量的对象. 完全由于使用大量的对象,造成很大的存储开销. 对象的大多数状态都可变为外部状态. 如果删除对象的外部状态, ...
- 设计模式之享元模式(FlyWeight)
#include <iostream> #include <string> #include <list> #include <vector> usin ...
随机推荐
- MySQL基础--字符函数
1.UPPER和UCASE返回字符串str,根据当前字符集映射(缺省是ISO-8859-1 Latin1)把所有的字符改变成大写.该函数对多字节是可靠的. 2.LOWER和LCASE返回字符串str, ...
- 在源文件(.c)和头文件(.h)中声明和定义的区别——C语言
最近在看多文件编程的时候遇到的一个问题,本来以为理解了声明和定义的区别(然而并没有····),也算是重新认识了一次声明和定义,下面上代码 情形一:在源文件(.c)中 相信大部分读者对声明和定义的理解是 ...
- java 手动实现远程执行功能(深入理解java虚拟机)
1.功能类 功能类共有五,分别是: package org.jvm; import java.io.*; /** * 对字节数组操作的工具类 */ public class ByteUtils { ...
- struts2框架学习笔记7:struts2标签
三大标签: 1.JSP:脚本,为了替代servlet,已过时 2.JSTL:标准标签库(core.format.sql.xml),还未淘汰的只有core库 3.Struts2标签库:由Struts2开 ...
- 第六篇: 分布式配置中心(Spring Cloud Config)
一.简介 在分布式系统中,由于服务数量巨多,为了方便服务配置文件统一管理,实时更新,所以需要分布式配置中心组件. 在Spring Cloud中,有分布式配置中心组件spring cloud confi ...
- PCIE 2.0协议概念基本科普
PCIE的概念:是电脑总线PCI的一种,它沿用现有的PCI编程概念及通信标准,但建基于更快的串行通信系统. 英特尔是该接口的主要支持者.PCIe仅应用于内部互连.由于PCIe是基于现有的PCI系统,只 ...
- Linux中matplotlib 中文显示问题解决
1.下载下载中文 arial unicode ms 字体到 /home 目录 2. 拷贝字体到 usr/share/fonts 下: sudo cp ~/arial\ unicode\ ms.ttf ...
- 递归查询区域信息及子区域到advTree
效果: DataTable dtArea = new DataTable(); private void Form1_Load(object sender, EventArgs e) { Node n ...
- sql 指定时间 所在的周、月、季、年
DECLARE @TodayDateTime DATETIMEDECLARE @strToday NVARCHAR(19) DECLARE @TodayBeginDateTime DATETIMEDE ...
- MVC笔记--特性路由
物性路由:将路由和控制器放在一起,这样更简单方便,还可以处理复杂的路由场景 传统路由:集中.强制.基于代码风格来定义的. 每个MVC应用程序都需要路由来定义自己的处理请求方式,路由是MVC是应用程序的 ...