flyweight pattern -- 享元模式

来源:互联网 发布:mac 键盘控制声音 编辑:程序博客网 时间:2024/05/22 08:27
 

flyweight pattern -- 享元模式

分类: 设计模式 257人阅读 评论(6) 收藏 举报
设计模式
内部状态与外部状态:  分离变与不变,共享不变,用接口实现 变化;
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文件
[cpp] view plaincopy
  1. #include <iostream>  
  2. float getFriction(std::string wheelname);  
  3. float getDrifting(std::string wheelname);  
  4. float getPorperty(std::string wheelname);  
  5. int getPamer(std::string brandname);  
  6. float getEffect(std::string brandname);  
  7. int getMaxSpeed(std::string makename);  
  8. int getAcceleration(std::string makename);  
function.cpp文件
[cpp] view plaincopy
  1. #include "function.h"   
  2. float getFriction(std::string wheelname)  
  3. {  
  4.     if(wheelname=="Michelin")return 240;  
  5.     else if(wheelname=="Bridgestone")return 200;  
  6.     else return -1;  
  7. }  
  8.   
  9. float getDrifting(std::string wheelname)  
  10. {  
  11.     if(wheelname=="Michelin")return 100;  
  12.     else if(wheelname=="Bridgestone")return 80;  
  13.     else return -1;  
  14. }  
  15.   
  16. float getPorperty(std::string wheelname)  
  17. {  
  18.     if(wheelname=="Michelin")return 0.03;  
  19.     else if(wheelname=="Bridgestone")return 0.02;  
  20.     else return -1;  
  21. }  
  22.   
  23. int getPamer(std::string brandname)  
  24. {  
  25.     if(brandname=="BMW"return 3;  
  26.     else if(brandname=="Ferrari")return 1;  
  27.     else if(brandname=="Benz")return 2;  
  28.     else if(brandname=="Audi")return 2;  
  29.     else return -1;  
  30. }  
  31.   
  32. float getEffect(std::string brandname)  
  33. {  
  34.     if(brandname=="BMW")return 0.8;  
  35.     else if(brandname=="Ferrari"return 0.4;  
  36.     else if(brandname=="Benz")return 0.6;  
  37.     else if(brandname=="Audi")return 0.6;  
  38.     else return -1;  
  39. }  
  40.   
  41. int getMaxSpeed(std::string makename)  
  42. {  
  43.     if(makename=="BMW")return 400;  
  44.     else if(makename=="Benz")return 400;  
  45.     else if(makename=="Ferrari"return 500;  
  46.     else if(makename=="redBull"return 480;  
  47.     else return -1;  
  48. }  
  49.   
  50. int getAcceleration(std::string makename)  
  51. {  
  52.     if(makename=="BMW")return 9;  
  53.     else if(makename=="Ferrari")return 10;  
  54.     else if(makename=="Benz"return 8;  
  55.     else if(makename=="redBull")return 8;  
  56.     else return -1;  
  57. }  
flyweight.cpp
[cpp] view plaincopy
  1. #include <utility>  
  2. #include <map>  
  3. #include "function.h"  
  4.   
  5. class wheel  
  6. {  
  7.     public:  
  8.         wheel(std::string n,float f,float d,float p)  
  9.         :name(n),friction(f),drifting(d),firstLoss(1),  
  10.         secondLoss(1),porperty(p)  
  11.         {}  
  12.         void run( );  
  13.         void doDrifting( );  
  14.     private:  
  15.         std::string name;  
  16.         float friction;  
  17.         float drifting;  
  18.         float firstLoss;  
  19.         float secondLoss;  
  20.         float porperty;  
  21. };  
  22.   
  23. void wheel::run()  
  24. {  
  25.     firstLoss=firstLoss*(1-porperty);  
  26.     friction=friction*firstLoss;  
  27.     std::cout<<" Tire wear"<<std::endl;  
  28. }  
  29.   
  30. void wheel::doDrifting()  
  31. {  
  32.     secondLoss=secondLoss*(1-porperty);  
  33.     drifting=drifting*secondLoss;  
  34.     std::cout<<" car is drifting"<<std::endl;  
  35. }  
  36.   
  37. class shell  
  38. {  
  39.     public:  
  40.         shell(std::string c)  
  41.         :color(c)  
  42.         {}  
  43.     private:  
  44.         std::string color;  
  45. };  
  46.   
  47. class brand  
  48. {  
  49.     public:  
  50.         brand(std::string n,int p,float e)  
  51.         :name(n),pamer(p),effect(e)  
  52.         {}  
  53.         int getPamer(){return pamer;}  
  54.         float getEffect(){return effect;}  
  55.     private:  
  56.         std::string name;  
  57.         int pamer;  
  58.         float effect;  
  59. };  
  60.   
  61. class engine  
  62. {  
  63.     public:  
  64.         engine(std::string m,int s,int a)  
  65.         :made(m),maxSpeed(s),acceleration(a)  
  66.         {}  
  67.         int accelerate(int speed,int t);  
  68.     private:  
  69.         std::string made;  
  70.         int maxSpeed;  
  71.         int acceleration;  
  72. };  
  73. int engine::accelerate(int speed,int t)  
  74. {  
  75.     if(speed<maxSpeed)  
  76.     {  
  77.         for(int i=1;i<=t;++i)  
  78.         {  
  79.             speed=speed+acceleration;  
  80.             if(speed>maxSpeed)  
  81.             {  
  82.                 speed=maxSpeed;  
  83.                 break;  
  84.             }  
  85.         }  
  86.     }  
  87.     std::cout<<" car is accelerating"<<std::endl;  
  88.     return speed;  
  89. }  
  90.   
  91. class car  
  92. {  
  93.     public:  
  94.         car(std::string n,wheel *w,shell *s,brand *b,engine *e)  
  95.         :name(n),_wheel(w),_shell(s),_brand(b),_engine(e),speed(0)  
  96.         {}  
  97.         void run( );  
  98.         void drifting();  
  99.         void accelerate(int t);  
  100.         void collide(const car *c);  
  101.         void showSpeed();  
  102.         std::string getName();  
  103.     private:  
  104.         std::string name;  
  105.         wheel * _wheel;  
  106.         shell* _shell;  
  107.         brand* _brand;  
  108.         engine* _engine;  
  109.         float speed;  
  110. };  
  111. std::string car::getName()  
  112. {  
  113.     return name;  
  114. }  
  115. void car::run()  
  116. {  
  117.     std::cout<<name;  
  118.     _wheel->run( );  
  119. }  
  120. void car::drifting()  
  121. {  
  122.     std::cout<<name;  
  123.     _wheel->doDrifting();  
  124. }  
  125. void car::accelerate(int t)  
  126. {  
  127.     std::cout<<name;  
  128.     speed=_engine->accelerate(speed,t);  
  129. }  
  130. void car::collide(const car* c)  
  131. {  
  132.     if(_brand->getPamer()>=c->_brand->getPamer())  
  133.     {  
  134.         std::cout<<name<<" car is stronger"<<std::endl;  
  135.     }  
  136.     speed=speed*c->_brand->getEffect( );  
  137. }  
  138.   
  139. void car::showSpeed()  
  140. {  
  141.     std::cout<<name<<" car's speed is "<<speed<<std::endl;  
  142. }  
  143.   
  144. class carFactory  
  145. {  
  146.     public:  
  147.         car* getcar(std::string carname,std::string wheelname,std::string  
  148.  color,std::string brandname,std::string makename);  
  149.         ~carFactory();  
  150.     private:  
  151.         std::map<std::string,wheel*> mw;  
  152.         std::map<std::string,shell*> ms;  
  153.         std::map<std::string,brand*> mb;  
  154.         std::map<std::string,engine*> me;  
  155. };  
  156.   
  157. car* carFactory::getcar(std::string carname,std::string wheelname,  
  158. std::string color,std::string brandname,std::string makename)  
  159. {  
  160.     wheel *w;  
  161.     std::map<std::string,wheel*>::iterator it1=mw.find(wheelname);  
  162.     if(it1==mw.end())  
  163.     {  
  164.         float friction=getFriction(wheelname);  
  165.         float drifting=getDrifting(wheelname);  
  166.         float porperty=getPorperty(wheelname);  
  167.         w=new wheel(wheelname,friction,drifting,porperty);  
  168.         mw.insert(std::pair<std::string,wheel*>(wheelname,w));  
  169.     }  
  170.     else  
  171.     {  
  172.         w=it1->second;  
  173.     }  
  174.     shell *s;  
  175.     std::map<std::string,shell*>::iterator it2=ms.find(color);  
  176.     if(it2==ms.end())  
  177.     {  
  178.         s=new shell(color);  
  179.         ms.insert(std::pair<std::string,shell*>(color,s));  
  180.     }  
  181.     else  
  182.     {  
  183.         s=it2->second;  
  184.     }  
  185.     brand *b;  
  186.     std::map<std::string,brand*>::iterator it3=mb.find(brandname);  
  187.     if(it3==mb.end())  
  188.     {  
  189.         float effect=getEffect(brandname);  
  190.         float pamer=getPamer(brandname);  
  191.         b=new brand(brandname,pamer,effect);  
  192.         mb.insert(std::pair<std::string,brand*>(brandname,b));  
  193.     }  
  194.     else  
  195.     {  
  196.         b=it3->second;  
  197.     }  
  198.     engine *e;  
  199.     std::map<std::string,engine*>::iterator it4=me.find(makename);  
  200.     if(it4==me.end())  
  201.     {  
  202.         int maxSpeed=getMaxSpeed(makename);  
  203.         int acceleration=getAcceleration(makename);  
  204.         e=new engine(makename,maxSpeed,acceleration);  
  205.         me.insert(std::pair<std::string,engine*>(makename,e));  
  206.     }  
  207.     else  
  208.     {  
  209.         e=it4->second;  
  210.     }  
  211.     return new car(carname,w,s,b,e);  
  212. }  
  213. carFactory::~carFactory()  
  214. {  
  215.     for(std::map<std::string,wheel*>::iterator it1=mw.begin();it1!=mw.end();)  
  216.     {  
  217.         delete it1->second;  
  218.         mw.erase(it1++);  
  219.     }  
  220.     for(std::map<std::string,shell*>::iterator it2=ms.begin();it2!=ms.end();)  
  221.     {  
  222.         delete it2->second;  
  223.         ms.erase(it2++);  
  224.     }  
  225.     for(std::map<std::string,brand*>::iterator it3=mb.begin();it3!=mb.end();)  
  226.     {  
  227.         delete it3->second;  
  228.         mb.erase(it3++);  
  229.     }  
  230.     for(std::map<std::string,engine*>::iterator it4=me.begin();it4!=me.end();)  
  231.     {  
  232.         delete it4->second;  
  233.         me.erase(it4++);  
  234.     }  
  235. }  
  236.   
  237. void collide(car* c1,car* c2)  
  238. {  
  239.     std::cout<<c1->getName()<<" and "<<c2->getName()<<" are collide "<<std::endl;  
  240.     c1->collide(c2);  
  241.     c2->collide(c1);  
  242. }  
  243.   
  244. int main(int argc,char** argv)  
  245. {  
  246.     carFactory* c=new carFactory( );  
  247.     car* c1=c->getcar("Han","Michelin","red","Ferrari","Ferrari");  
  248.     car* c2=c->getcar("Bei","Bridgestone","white","BMW","BMW");  
  249.     car* c3=c->getcar("Wu","Michelin","red","Benz","Ferrari");  
  250.     c1->accelerate(40);  
  251.     c2->accelerate(40);  
  252.     c3->accelerate(40);  
  253.     c1->run();  
  254.     c2->run();  
  255.     c3->run();  
  256.     c1->drifting();  
  257.     c2->drifting();  
  258.     c3->drifting();  
  259.     c1->showSpeed();  
  260.     c2->showSpeed();  
  261.     c3->showSpeed();  
  262.     collide(c1,c3);  
  263.     c1->showSpeed();  
  264.     c2->showSpeed();  
  265.     c3->showSpeed();  
  266.         delete c;  
  267.         delete c1;  
  268.         delete c2;  
  269.         delete c3;  
  270.         return 0;  
  271. }  
运行结果
如果有兴趣可以继续浏览该系列文章:
singleton pattern--单件模式
factory mothed pattern--工厂方法模式
abstract factory pattern--抽象工厂模式
builder pattern--建造者模式
prototype pattern--原型模式
adapter pattern--适配器模式
bridge pattern -- 桥接模式
composite pattern -- 组合模式
decorator pattern -- 装饰模式
flyweight pattern -- 享元模式
原创粉丝点击