设计模式之策略模式(c++实现)

一、前言

最近开始学习Head First Design Patterns,再记录一些学习过程中的笔记,增强记忆。

选择Head First Design Patterns这本书的原因比较简单,比较适合我这个半路出家的程序员。


二、基本内容

策略模式(strategy patterns):

定义了算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。


三、代码

以设计谜题为背景:设计一款动作冒险游戏,每个角色一次只能使用一种武器,但是可以在游戏中更换武器。


准则1:找到变化的部分,变化的部分即武器是可以变换的,因此要将其独立出来,并将它们作为算法族封装

定义一个基类的接口

class WeaponBehavior {
public:
    WeaponBehavior(string name, string texture)
        :name(name),texture(texture)
    {
    }
    virtual void useWeapon()
    {
        std::cout << "using " << texture << " " << name << endl;
    }
protected:
    string name;
    string texture;
};

其中useWeapon作为武器的接口方法,不同的武器都有自己的使用方法和效果,这里定义三种武器

class KnifeBehavior : public WeaponBehavior
{
public:
    KnifeBehavior():WeaponBehavior("sword", "iron")
    {
    }
    virtual void useWeapon()
    {
        cout << "Equip Swiss Army Knife" << endl;
    }
};

class KatyushaRocketBehavior : public WeaponBehavior
{
public:
    KatyushaRocketBehavior():WeaponBehavior("wand", "wood")
    {
    }
    virtual void useWeapon()
    {
        cout << "Katyusha Rocket start... Boom" << endl;
    }
};
class AxeBehavior : public WeaponBehavior
{
public:
    AxeBehavior():WeaponBehavior("axe", "iron")
    {
    }

    virtual void useWeapon()
    {
        cout << "Equip AXE" << endl;
    }
};

准则2:针对接口编程而不是针对supertype

准则3:多用组合少用继承

定义角色的基类

class Character {
public:
    Character(string name, string gender, WeaponBehavior *weaponBehavior)
        :name(name),gender(gender),weaponBehavior(weaponBehavior)
    {
    }
    string GetName()
    {
        return name;
    }
    void SetName(string name)
    {
        this->name = name;
    }
    string GetGender()
    {
        return gender;
    }
    void SetGender(string gender)
    {
        this->gender = gender;
    }
    void fight()
    {
        weaponBehavior->useWeapon();
    }
    void setWeapon(WeaponBehavior *wb)
    {
        this->weaponBehavior = wb;
    }
    void show()
    {
        cout << name << ":" << gender << endl;
    }
protected:
    string name;
    string gender;
    WeaponBehavior *weaponBehavior;
};


定义角色 “亚瑟王”和“痛苦女王”

class King : public Character
{
public:
    King(WeaponBehavior *weaponBehavior):Character("King Arthur", "male", weaponBehavior)
    {
    }
};
class Queen : public Character
{
public:
    Queen(WeaponBehavior *weaponBehavior):Character("Queen Akasha", "female", weaponBehavior)
    {
    }
};

赋予亚瑟王一把瑞士军刀,赋予痛苦女王喀秋莎火箭炮,然后半路亚瑟王打怪得到一把战斧。

int SimUGame() 
{
    KnifeBehavior *knife = new KnifeBehavior();
    King king(knife);
    KatyushaRocketBehavior *rocket = new KatyushaRocketBehavior();
    Queen queen(rocket);
    king.show();
    king.fight();
    queen.show();
    queen.fight();
    AxeBehavior *axe = new AxeBehavior();
    king.setWeapon(axe);
    king.fight();
    delete knife;
    delete rocket;
    delete axe;
    return 0;
}


四、UML类图



code path: https://github.com/niceukulele/DesignPatternStudy.git


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值