一、前言
最近开始学习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