设计模式-策略模式

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

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

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

先看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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值