享元模式顾名思义就是羽量级模式或者蝇级模式,形容体量小的应用,该模式主要的设计目的是为了迎合系统大量相似数据的应用而生,减少用于创建和操作相似的细碎对象所花费的成本。大量的对象会消耗高内存,享元模式给出了一个解决方案,即通过共享对象来减少内存负载。
<强>作用强>
通过复用相同的对象来减少对象的创建数量,创建更小的对象组,并通过共享实现重用。通过归类,将对象的属性分为内蕴状态和外蕴状态。要创建具体的享元对象,我们需要创建一个享元工厂来统一管理对象的生成和输出,享元工厂是实现享元模式的关键。
举个例子,享元模式可以看成是一个工具箱,而享元对象就是工具箱内的具体的工具,我们在使用工具的时候,不必每回临时的制造工具,而是直接从工具箱里找到工具进行使用,这样就大大节约了制造工具的成本时间和工具占用的空间。
享元模式比较迷惑在于理解两种状态的分类,内蕴状态是对象本身的属性,在生成对象以后一般不会进行改变,比如工具中的属性:名字,大小,重量等,还有就是我们一般需要一个关键性的属性作为其区别于其他对象的关键,如工具的话我们可以把名称作为找到工具的唯一标识。
外蕴状态是对象的外部描述,是每个对象的可变部分,比如对工具的使用地点,使用时间,使用的人,工作内容的描述,这些属性不属于对象本身,而是根据每回使用情况进行变化的,这就需要制作成接口进行外部调用,而外蕴状态的维护是由调用者维护的,对象内不进行维护。
<强>类视图强>
<>强实现强>
//轻量级 类工具 { 公众://内蕴状态 字符串名称; int nSize; int nWeight; 公众://外蕴状态 使用虚拟int(字符串,字符串工作)=0; }//ConcreteFlyweight 锤类:公共工具 { 公众: 锤():名称(“锤”){} 使用int(字符串,字符串工作) { cout<& lt;人& lt; & lt;“使用”& lt; & lt; name<& lt;”到“& lt; & lt;工作; } }//ConcreteFlyweight 类螺丝刀:公共工具 { 螺丝刀():名称(“螺丝刀”){} 使用int(字符串,字符串工作) { cout<& lt;人& lt; & lt;“使用”& lt; & lt;名字& lt; & lt;”到“& lt; & lt;工作; } }//ConcreteFlyweight 类看到:公共工具 { 看到():名称(“看到”){} 使用int(字符串,字符串工作) { cout<& lt;人& lt; & lt;“使用”& lt; & lt;名字& lt; & lt;”到“& lt; & lt;工作; } }//FlyweightFactory 类的工具箱 { 公众: 工具箱(); 虚拟~工具箱() { map<字符串,工具*祝辞::iterator它=m_tool.find (toolname); 为(=m_tool.begin();它!=m_tool.end (); + +) { 删除it.second; } } 工具* GetTool(字符串toolname) { map<字符串,工具*祝辞::iterator它=m_tool.find (toolname); 如果(它!=m_tool.end ()) { 返回(工具*)it.second; } 其他的 { 工具* tooltemp=零; 如果(toolname==按浮? tooltemp=new锤(); else if (toolname==奥菟康丁? tooltemp=new螺丝刀(); else if (toolname==翱吹健? tooltemp=new看到(); 如果(tooltemp !=NULL) m_tool.insert (make_pair<字符串,工具*祝辞(toolname tooltemp)); 返回tooltemp; } } 私人: map<字符串,工具*比;m_tool; } int main () {//外蕴状态由调用者维护 字符串person1=皕hangsan”; 字符串person2=發isi”; 字符串work1=白雷印? 字符串work2=靶蘩碜孕谐怠?//生成工厂 工具箱tBox;//获取享元 工具* tool1=tBox.GetTool(“锤”); tool1.used (person1 work1); 工具* tool2=tBox.GetTool(“螺丝刀”); tool2.used (person2 work2); } >之前单享元(分享)和复合享元(共享)
复合享元也既是unshareFlyweight,其不再是单一的对象,而是一系列对象的组合,他们的关系由原来的一对一的关系,变成了一对多的关系。
举例说明,如【DP】中比较经典的围棋的例子,单享元模式下,我们对围棋的颜色种类进行共享,再棋盘的工厂类中只需包含黑白两颗棋子,就能完成对棋盘下棋的整个操作,而不用对每一个棋子进行操作。但是有一天需求增加了对胜负的要求,那么就需要对棋子的坐标进行记录,对于黑白两种颜色的棋子,相对应的就会有相同颜色棋子的坐标数组容器,如:mapc++设计模式之享元模式(轻量级)