flyweight pattern 又称享元模式
Use sharing to support large numbers of fine-grained objects efficiently --- GoF
运用共享技术有效地支持大量细粒度的对象
UnshareConcreteFlyweight:
并不是所有的Flyweight具体实现子类都需要被共享的,如果是不能共享的,那么就只能是它只能被引用一个。
ConcreteFlyweight:
可以被共享,该对象可以被多个引用。
还是以汽车模型为例子,例如我们来建立一个跑车的部分场景,每个赛车都有轮胎,外壳,品牌,引擎
这个部分组成,轮胎影响飘逸和刹车的效果,外壳仅仅是外观效果,引擎影响最大速度和加速度,品牌影响可以被撞后影响。我们游戏会有40辆车,如果构建这20辆车需要160个对象,但是我们发现这160个对象太消耗系统性能与资源了,其实有些对象是一样的的,那么在这个场景中,完全可以共享这些对象,那么这样
可以节省好多对象的构造与析构,系统牺牲一定空间来提升性能与效率。
轮胎有:米其林,普利司通两种轮胎
Michelin轮胎:摩擦系数很高,漂移效果好,损耗很高
Bridgestone轮胎:摩擦细数一般,漂移效果一般,损耗一般
外壳有:红色,黑色,白色,蓝色,绿色,黄色,紫色七种
品牌有:宝马,法拉利,奥迪,奔驰四种
BMW:坚固性强,被撞减速一般
Ferrari: 坚固性弱,被减速大
Audi:坚固性一般,被减速大
Benz:坚固性一般,被减速小
引擎:法拉利研制,红牛研制,奔驰研制,宝马研制
Ferrari:速度高,加速高
Redbull:速度高,加速一般
Benz:速度一般,加速一般
BMW:速度一般,加速快
模拟从数据库或者配置表里获得数据
function.h文件
- #include <iostream>
- float getFriction(std::string wheelname);
- float getDrifting(std::string wheelname);
- float getPorperty(std::string wheelname);
- int getPamer(std::string brandname);
- float getEffect(std::string brandname);
- int getMaxSpeed(std::string makename);
- int getAcceleration(std::string makename);
function.cpp文件
- #include "function.h"
- float getFriction(std::string wheelname)
- {
- if(wheelname=="Michelin")return 240;
- else if(wheelname=="Bridgestone")return 200;
- else return -1;
- }
-
- float getDrifting(std::string wheelname)
- {
- if(wheelname=="Michelin")return 100;
- else if(wheelname=="Bridgestone")return 80;
- else return -1;
- }
-
- float getPorperty(std::string wheelname)
- {
- if(wheelname=="Michelin")return 0.03;
- else if(wheelname=="Bridgestone")return 0.02;
- else return -1;
- }
-
- int getPamer(std::string brandname)
- {
- if(brandname=="BMW") return 3;
- else if(brandname=="Ferrari")return 1;
- else if(brandname=="Benz")return 2;
- else if(brandname=="Audi")return 2;
- else return -1;
- }
-
- float getEffect(std::string brandname)
- {
- if(brandname=="BMW")return 0.8;
- else if(brandname=="Ferrari") return 0.4;
- else if(brandname=="Benz")return 0.6;
- else if(brandname=="Audi")return 0.6;
- else return -1;
- }
-
- int getMaxSpeed(std::string makename)
- {
- if(makename=="BMW")return 400;
- else if(makename=="Benz")return 400;
- else if(makename=="Ferrari") return 500;
- else if(makename=="redBull") return 480;
- else return -1;
- }
-
- int getAcceleration(std::string makename)
- {
- if(makename=="BMW")return 9;
- else if(makename=="Ferrari")return 10;
- else if(makename=="Benz") return 8;
- else if(makename=="redBull")return 8;
- else return -1;
- }
flyweight.cpp
- #include <utility>
- #include <map>
- #include "function.h"
-
- class wheel
- {
- public:
- wheel(std::string n,float f,float d,float p)
- :name(n),friction(f),drifting(d),firstLoss(1),
- secondLoss(1),porperty(p)
- {}
- void run( );
- void doDrifting( );
- private:
- std::string name;
- float friction;
- float drifting;
- float firstLoss;
- float secondLoss;
- float porperty;
- };
-
- void wheel::run()
- {
- firstLoss=firstLoss*(1-porperty);
- friction=friction*firstLoss;
- std::cout<<" Tire wear"<<std::endl;
- }
-
- void wheel::doDrifting()
- {
- secondLoss=secondLoss*(1-porperty);
- drifting=drifting*secondLoss;
- std::cout<<" car is drifting"<<std::endl;
- }
-
- class shell
- {
- public:
- shell(std::string c)
- :color(c)
- {}
- private:
- std::string color;
- };
-
- class brand
- {
- public:
- brand(std::string n,int p,float e)
- :name(n),pamer(p),effect(e)
- {}
- int getPamer(){return pamer;}
- float getEffect(){return effect;}
- private:
- std::string name;
- int pamer;
- float effect;
- };
-
- class engine
- {
- public:
- engine(std::string m,int s,int a)
- :made(m),maxSpeed(s),acceleration(a)
- {}
- int accelerate(int speed,int t);
- private:
- std::string made;
- int maxSpeed;
- int acceleration;
- };
- int engine::accelerate(int speed,int t)
- {
- if(speed<maxSpeed)
- {
- for(int i=1;i<=t;++i)
- {
- speed=speed+acceleration;
- if(speed>maxSpeed)
- {
- speed=maxSpeed;
- break;
- }
- }
- }
- std::cout<<" car is accelerating"<<std::endl;
- return speed;
- }
-
- class car
- {
- public:
- car(std::string n,wheel *w,shell *s,brand *b,engine *e)
- :name(n),_wheel(w),_shell(s),_brand(b),_engine(e),speed(0)
- {}
- void run( );
- void drifting();
- void accelerate(int t);
- void collide(const car *c);
- void showSpeed();
- std::string getName();
- private:
- std::string name;
- wheel * _wheel;
- shell* _shell;
- brand* _brand;
- engine* _engine;
- float speed;
- };
- std::string car::getName()
- {
- return name;
- }
- void car::run()
- {
- std::cout<<name;
- _wheel->run( );
- }
- void car::drifting()
- {
- std::cout<<name;
- _wheel->doDrifting();
- }
- void car::accelerate(int t)
- {
- std::cout<<name;
- speed=_engine->accelerate(speed,t);
- }
- void car::collide(const car* c)
- {
- if(_brand->getPamer()>=c->_brand->getPamer())
- {
- std::cout<<name<<" car is stronger"<<std::endl;
- }
- speed=speed*c->_brand->getEffect( );
- }
-
- void car::showSpeed()
- {
- std::cout<<name<<" car's speed is "<<speed<<std::endl;
- }
-
- class carFactory
- {
- public:
- car* getcar(std::string carname,std::string wheelname,std::string
- color,std::string brandname,std::string makename);
- ~carFactory();
- private:
- std::map<std::string,wheel*> mw;
- std::map<std::string,shell*> ms;
- std::map<std::string,brand*> mb;
- std::map<std::string,engine*> me;
- };
-
- car* carFactory::getcar(std::string carname,std::string wheelname,
- std::string color,std::string brandname,std::string makename)
- {
- wheel *w;
- std::map<std::string,wheel*>::iterator it1=mw.find(wheelname);
- if(it1==mw.end())
- {
- float friction=getFriction(wheelname);
- float drifting=getDrifting(wheelname);
- float porperty=getPorperty(wheelname);
- w=new wheel(wheelname,friction,drifting,porperty);
- mw.insert(std::pair<std::string,wheel*>(wheelname,w));
- }
- else
- {
- w=it1->second;
- }
- shell *s;
- std::map<std::string,shell*>::iterator it2=ms.find(color);
- if(it2==ms.end())
- {
- s=new shell(color);
- ms.insert(std::pair<std::string,shell*>(color,s));
- }
- else
- {
- s=it2->second;
- }
- brand *b;
- std::map<std::string,brand*>::iterator it3=mb.find(brandname);
- if(it3==mb.end())
- {
- float effect=getEffect(brandname);
- float pamer=getPamer(brandname);
- b=new brand(brandname,pamer,effect);
- mb.insert(std::pair<std::string,brand*>(brandname,b));
- }
- else
- {
- b=it3->second;
- }
- engine *e;
- std::map<std::string,engine*>::iterator it4=me.find(makename);
- if(it4==me.end())
- {
- int maxSpeed=getMaxSpeed(makename);
- int acceleration=getAcceleration(makename);
- e=new engine(makename,maxSpeed,acceleration);
- me.insert(std::pair<std::string,engine*>(makename,e));
- }
- else
- {
- e=it4->second;
- }
- return new car(carname,w,s,b,e);
- }
- carFactory::~carFactory()
- {
- for(std::map<std::string,wheel*>::iterator it1=mw.begin();it1!=mw.end();)
- {
- delete it1->second;
- mw.erase(it1++);
- }
- for(std::map<std::string,shell*>::iterator it2=ms.begin();it2!=ms.end();)
- {
- delete it2->second;
- ms.erase(it2++);
- }
- for(std::map<std::string,brand*>::iterator it3=mb.begin();it3!=mb.end();)
- {
- delete it3->second;
- mb.erase(it3++);
- }
- for(std::map<std::string,engine*>::iterator it4=me.begin();it4!=me.end();)
- {
- delete it4->second;
- me.erase(it4++);
- }
- }
-
- void collide(car* c1,car* c2)
- {
- std::cout<<c1->getName()<<" and "<<c2->getName()<<" are collide "<<std::endl;
- c1->collide(c2);
- c2->collide(c1);
- }
-
- int main(int argc,char** argv)
- {
- carFactory* c=new carFactory( );
- car* c1=c->getcar("Han","Michelin","red","Ferrari","Ferrari");
- car* c2=c->getcar("Bei","Bridgestone","white","BMW","BMW");
- car* c3=c->getcar("Wu","Michelin","red","Benz","Ferrari");
- c1->accelerate(40);
- c2->accelerate(40);
- c3->accelerate(40);
- c1->run();
- c2->run();
- c3->run();
- c1->drifting();
- c2->drifting();
- c3->drifting();
- c1->showSpeed();
- c2->showSpeed();
- c3->showSpeed();
- collide(c1,c3);
- c1->showSpeed();
- c2->showSpeed();
- c3->showSpeed();
- delete c;
- delete c1;
- delete c2;
- delete c3;
- return 0;
- }
运行结果
如果有兴趣可以继续浏览该系列文章:
singleton pattern--单件模式
factory mothed pattern--工厂方法模式
abstract factory pattern--抽象工厂模式
builder pattern--建造者模式
prototype pattern--原型模式
adapter pattern--适配器模式
bridge pattern -- 桥接模式
composite pattern -- 组合模式
decorator pattern -- 装饰模式
flyweight pattern -- 享元模式