设计模式-策略模式

来源:互联网 发布:人工智能产品有哪些 编辑:程序博客网 时间:2024/06/05 11:02

策略模式的核心思路:将一个个算法分别封装来,使用算法的客户可以任意地替换任何一种算法

策略模式最大的好处:当算法发生改变时,不会对算法的使用方式造成影响,也就是算法跟算法客户分别独立

下面进行讲解:
场景:古代战争中,士兵对武器(大剑、长毛、弓箭)的选择就是一种策略模式,士兵可以自由选择自己擅长得武器进行战斗。

先看UML图:

这里写图片描述

实现此场景需要3个角色:
1、武器抽象,定义了Attck接口
2、具体的武器(大剑、长毛、弓箭),分别实现Attck接口
3、士兵,选择具体的武器,然后进行攻击

代码实现:

__interface IWeapon{public:    virtual void Attack() = 0;}; class CSword:public IWeapon{public:    virtual void Attack() { cout << "大剑攻击!" << endl; }};class CSpear{public:    virtual void Attack() { cout << "长矛攻击!" << endl; }};class CArrow{public:    virtual void Attack() { cout << "弓箭射击!" << endl; }};class CSoldier{public:    void  SetWeapon(IWeapon*  wp) { m_pWeapon = wp; }    void  Attack() { m_pWeapon->Attack(); }private:    IWeapon*    m_pWeapon;};

客户端的调用颇为繁琐:

int main(){    CSoldier  joson;    IWeapon*  pSword = new CSword();    joson.SetWeapon(pSword);//使用大剑    joson.Attack();    delete pSword;    IWeapon*  pArrow = new CArrow();    joson.SetWeapon(pArrow);//使用弓箭    joson.Attack();    delete pArrow;    return 0;}



与简单工厂模式结合:

为了避免客户端直接跟各种“策略”打交道,可以考虑与简单工厂模式结合使用:定义一个枚举类型,通过传递标签的方式让策略在策略上下文中创建。

武器类没有变化,这里只贴出士兵类和客户端的代码:

class CSoldier{public:    enum Weapon_Type{WEAPON_SWORD,WEAPON_SPEAR,WEAPON_ARROW};    CSoldier() { m_pWeapon = NULL; }    ~CSoldier() { Release(); }    void  SetWeapon(Weapon_Type  eType) {         Release();        switch (eType)        {        case CSoldier::WEAPON_SWORD:            m_pWeapon = new CSword();            break;        case CSoldier::WEAPON_SPEAR:            m_pWeapon = new CSpear();            break;        case CSoldier::WEAPON_ARROW:            m_pWeapon = new CArrow();            break;        default:            break;        }    }    void  Attack() { m_pWeapon->Attack(); }    void  Release() {        if (m_pWeapon != NULL)            delete m_pWeapon;    }private:    IWeapon*    m_pWeapon;};int main(){    CSoldier  joson;    joson.SetWeapon(CSoldier::WEAPON_SPEAR);//使用长矛    joson.Attack();    joson.SetWeapon(CSoldier::WEAPON_SWORD);//使用大剑    joson.Attack();    joson.SetWeapon(CSoldier::WEAPON_ARROW);//使用弓箭    joson.Attack();    return 0;}

最后,附上完整代码:
http://pan.baidu.com/s/1qXBYoHY

0 0
原创粉丝点击