设计模式之策略模式

来源:互联网 发布:巨人城刷龙啸翻牌软件 编辑:程序博客网 时间: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接口了。怎么样这样的设计是不是很熟?