设计模式之策略模式
来源:互联网 发布:巨人城刷龙啸翻牌软件 编辑:程序博客网 时间:2024/04/23 20:57
设计模式之策略模式
策略模式定义了算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。策略模式体现了三个设计原则:
Ø 原则一、变化与不变化分离原则,将应用中可能出现的变化部分封装起来,和不变的部分进行分离,使不变的部分不受影响,代码变化导致的不可控因素变少,系统更具有弹性;
Ø 原则二、针对接口编程,而不是对实现编程,接口代表是每个行为,提供专门类来实现这些行为。
Ø 原则三、多用组合,少用继承。使用组合不仅可以将算法族封装成类,也可以“在运行时动态改变行为”
策略模式的模型如下:
这样实现的有点:
一、接口的变换不影响对象;某些对象不具有的接口,可以不实现该对象的接口。
二、接口与实现解耦,接口可以重用;.
三、可以通过“设定方法”动态地改变对象的行为;
引用书中的例子,一个动作冒险游戏,里面有4中角色:King,Queen,Knight和Troll,他们可以使用不同的武器进行战斗,武器包括:匕首,弓箭,斧头和宝剑,我们可以这样做:
首先,提取出可变的部分使用武器战斗的接口作为一个方法族,并且分别实现匕首、弓箭、斧头和宝剑的战斗方法。
ClassWeaponBehavior
{
Virtual void UseWeapon()=0;
Virtual ~weaponBehavior() {}
}
ClassNoweaponBehavior : public WeaponBehavior
{
Void UseWeapon() {
Cout<<”NoWeapon fight”<<endl;
}
}
ClassKnifeBehavior : public WeaponBehavior
{
Void UseWeapon() {
Cout<<”UseKnife fight”<<endl;
}
}
ClassBowAndArrowBehavior : public WeaponBehavior
{
Void UseWeapon(){
Cout<<”Use Bowand Arrow fight”<<endl;
}
}
ClassAxeBehavior : public WeaponBehavior
{
Void UseWeapon(){
Cout<<”Use Axe fight”<<endl;
}
}
ClassSwordBehavior : public WeaponBehavior
{
Void UseWeapon(){
Cout<<”Use Sword fight”<<endl;
}
}
其次定义一个角色的基类,该类中包含武器的对象,设置武器的方法,以及使用武器战斗的方法,分别定义King、Queen、Knight和Troll三个类分别继承该基类
Class Character
{
WeaponBehavior* weapon;
Public:
void setweapon(WeaponBehavior w) { deleteweapon; weapon = w;}
void fight() {weapon->UseWeapon();}
void Display(){cout<<”I am Character”<<endl;}
virtual ~Character(){delete weapon;}
}
Class king :public Character
{
Void Display(){cout<<”I am King”<<endl;}
}
Class Queen :public Character
{
Void Display(){cout<<”I am Queen”<<endl;}
}
Class knight :public Character
{
Void Display(){cout<<”I am Knight”<<endl;}
}
Class troll :public Character
{
Void Display(){cout<<”I am Troll”<<endl;}
}
最后,在实现中每个角色都可以灵活的使用各种武器战斗
int main()
{
Character* pcharacter = new king(newNoweapen);
pcharacter->Display();
pcharacter->fight();
pcharacter->setweapon(new Sword);
pcharacter->fight();
delete pcharacter;
return 0;
}
策略模式是否可以在C语言中使用呢?答案是肯定的,策略模式的本质是将实现的变换部分和不变部分分离,将变化部分封装成方法族,从而降低局部变化部影响系统的风险。因此C语言完全可以使用策略模式,其实现模型:
一、定义变化方法的接口结构。
二、提供变化方法的注册接口。
三、不变部分实现中使用钩子函数调用变化的方法。
例如有三个模块A、B、C,他们分别不同的数据结构,但是他们在实现某个功能时都有固定的步骤:update,preproc,process,response。由于模块A、B、C具有结构不同数据结构,update,preproc,process三个步骤的实现不同。那么可以这么实现:
定义变化方法的接口结构:
typedef void (*update)();
typedef void (*preproc)();
typedef void (*process)();
struct stFunc
{
update pFuncUpdate;
preproc pFuncPrproc;
process pFuncProcess;
}
提供一个变化方法的接口注册函数
stFunc* gFunc = NULL;
void registerFunc(stFunc* F) {gFunc = F;}
固定部分通过钩子函数调用变化的方法
Voidfunction()
{
gFunc->update();
gFunc->preproc();
gFunc->process();
response();
}
模块A、B、C分别实现自己的update,preproc和process方法,先调用registerFunc接口注册变化的接口,再调用function()方法实现该功能。当然如果三个模块接口实现一样,也可以共有一个函数,或者A和B的update方法一样,那么A和B就可以共有update接口了。怎么样这样的设计是不是很熟?
- 设计模式之策略模式
- 设计模式之策略模式
- 设计模式之策略模式
- 设计模式之策略模式
- 设计模式之策略模式
- 设计模式之策略模式
- 设计模式之策略模式
- 设计模式之策略模式
- 设计模式之策略模式
- 设计模式之策略模式
- 设计模式之策略模式
- 设计模式之策略模式
- 设计模式之策略模式
- 设计模式之策略模式
- 设计模式之策略模式
- 设计模式之策略模式
- 设计模式之策略模式
- 设计模式之策略模式
- 11.读书笔记收获不止Oracle之 表设计之分区使用
- 12.读书笔记收获不止Oracle之 索引分区表
- web.xml
- 13.读书笔记收获不止Oracle之 簇表
- Ubuntu内核升级以及如何开启BBR加速
- 设计模式之策略模式
- 聊聊PhoneWindow,getDecorView(),setContentView
- 14.读书笔记收获不止Oracle之 索引
- 关于反码,byte最大值127,最小值-128的由来缘由以及书本上从未讲解过的反码补码功能作用
- USB接口的功能和区分全解析
- 226. Invert Binary Tree Difficult: Easy
- pos1007
- 静态链接库(.lib)和动态链接库(.dll)的区别和使用
- 15.读书笔记收获不止Oracle之 索引高度