目录
1、Flyweight
(1)意图
(2)结构
(3)适用性
2、根据uml编写代码
(1)泛化关系
(2)关联关系
(3)UML的理解
3、代码实现
1、Flyweight
(1)意图
运用共享技术有效地支持大量细粒的对象
(2)结构
flyweight描述一个接口,通过这个接口flyweight可以接受并作用于外部状态。
concreteflywegiht实现flyweight接口,并为内部状态增加储存空间,concreteflyweight对向必须可共享的。它所储存的状态必须是内部的,它必须独立于concreteflyweight对象的场景。
并非所有的flyweight子类都需要被共享。flyweight接口使共享成为可能,但并不强制共享。在flyweight对象结构的某些层次,unsharedconcreteflyweight对象通常将concreteflayweight对象作为子节点。
flyweightfactory创建并非管理flyweight对象;确保合理的共享flyweight,当用户请求一个flyweight时,flyweight对象提供一个创建的实例或者在不存在时创建一个实例。
client唯一一个对flyweight的引用;计算或储存一个或多个flyweight的外部状态。
(3)适用性
一个应用程序使用了大量的对象。
完全由于使用大量的对象,造成很大开销。
对象的大多数状态都可以为外部状态。
如果删除兑现的外部状态,那么可以用相对较少共享对象取代多组对象。
应用程序不依赖于对象标识,由于flyweight对象可被共享,所以对于概念上明显有别的对象,表示测试将返回真值。
2、根据uml编写代码
(1)泛化关系
所谓泛化关系,我们简单里的理解即为为父类与子类的关系,本uml图中flyweight类为unsharedconcreteflyweigh类和concreteflayweight类的父类。
(2)关联关系
flyweightfactory为flyweight特殊关联关系聚合,即在flyweightfactory中有一个“flyweight*”指向flyweight的指针,实现对flyweight的操作。
(3)UML的理解
首先我们根据教材适用性来理解,一个应用程序使用了大量的对象;完全由于使用大量的对象,造成很大开销;对象的大多数状态都可以为外部状态。通过这三句话我们可以做如下理解,假如我们要开发一个卖咖啡和茶的饮料店软件,那么我们卖出一个红茶要new一个对象,我们生成一个绿茶又要new一个对象,我们做一个抹茶又要new一个对象。这样我们的茶类的商品约丰富我们需要new的东西就越来越多。咖啡类商品也一样,奶昔咖啡要new、摩卡要new,假如咖啡种类也很多我们需要new的内容也会越来越多,这就意味着我们使用大量的对象,意味着有大量的开销
假如我们做如下假设:
奶昔咖啡分为=咖啡+奶昔部分;
那么拿铁咖啡=咖啡+拿铁部分;
如果我们这样实现程序的表现的化,奶昔咖啡和拿铁的咖啡部分就可以共用一个new。奶昔部分和拿铁部分我们可以把它理解为外部状态,在实际操作中我们可以用一个链表对外部状态进行储存,若有必要我们可以进行操作或者修改,例如飞行游戏中,飞机射出大量的子弹,我们可以享元模式中,众多子弹可以公用一个new,子弹在界面的位置可以作为外部变量存在链表之中,按时间推移,我们修改子弹的图的位置实现子弹运动的效果。
UML图中也有不允许共享的部分,这点非常好理解,还是卖咖啡和茶的饮料店的店的例子,这个饮料点如果它也卖可乐、雪碧等第三方饮料,这种不允许像咖啡那样找一个部分用于共享了。
3、代码实现
暂未写析构部分
#include#include using namespace std; class taset{//用于存储外部状态 public: taset(string mixture){ this->mixture=mixture; } string mixture; }; class flyweight{//饮料店 public: virtual void operation()=0; virtual void operation(const string& ,const string&)=0; string taste; }; class concreteflyweight_tea:public flyweight{//煮茶部分 public: void operation(){ cout<<"复杂的煮茶过程"<
operation(key,this_taset); } } void findtaset(flyweight *drink,string this_taset){ typedef list ::iterator IT; for(IT it=mylist.begin();it!=mylist.end();it++){//通过对链表进行遍历,若表中存有就直接使用,没有就创建一个并存在链表中 if((*it)->mixture==this_taset){ cout< operation(); return ;//找到后马上return结束该方法 } } cout< operation(); } private: list mylist; flyweight *tea; flyweight *cofee; flyweight *other;//非共享 }; int main(){ flyweightfactory* a=new flyweightfactory; a->getflyweight( "tea","抹茶" ); a->getflyweight( "茶","抹茶" ); a->getflyweight( "tea","红茶" ); a->getflyweight( "cofee","奶昔" ); a->getflyweight( "tea","红茶" ); a->getflyweight( "tea","红茶" ); a->getflyweight( "咖啡","奶昔" ); a->getflyweight( "可乐","冰" ); return 0; }
运行结果:



