“模板方法模式的本质是固定算法骨架。通过固定算法骨架来约束子类的行为,并在特定的扩展点来让子类进行功能扩展, 从而让程序既有很好的复用性,又有较好的扩展性。 各个子类中有公共行为,为了避免代码重复,应该提取到父类实现。 需要固定算法骨架,并要子类来实现一些可变的部分。”
看具体的例子如下:
在软件设计中 某一个算法的步骤是固定的 但是每个步骤都是有可能变化的 那么我们就可以使用模板方法来设计我们的系统 比如说
只要是个Fighter他就可以攻击 攻击中固定的三个步骤是 拿出武器 攻击敌人 然后播放攻击动画 那么我们攻击中的三个步骤是永远不会发生改变的 这是稳定点 但是我们的三个步骤都可以是有不同的实现的 比如说 法师的拿出武器步骤就是拿出法杖 而战士的拿出武器步骤是拿出锤子 他们的攻击敌人的步骤肯定也不相同 播放的攻击动画肯定也不相同 所以我们就可以先把整个骨架搭好 至于具体的实现我们可以延迟到子类中去实现 具体的UML类图如下
实现代码如下
#include<iostream>
//模板方法设计模式定义了一个操作中的骨架 而把骨架中零散可变化的步骤给抽象出来 延迟到具体实现中去
//比如咋们Fighter作为父类 所有的Fighter都能够攻击 攻击就一定是拿出武器 伤害敌人 播放攻击动画 那么我们就可以定义这个攻击算法的骨架 这个攻击算法是一定不会变的
#include<memory>
class Fighter
{
public:
Fighter(int hp, int mp, int attck) :hp_(hp), mp_(mp), attck_(attck) {}
virtual ~Fighter() {};
void attack()
{
TakeWeapon();
TakeDamage();
PlayAttackAnimation();
}//这个算法就定义了骨架
private:
virtual void TakeWeapon() = 0;
virtual void TakeDamage() = 0;
virtual void PlayAttackAnimation() = 0;
int hp_;
int mp_;
int attck_;
};
//是Fighter的角色有 战士 法师 他们拿出武器造成伤害和播放的动画各不相同
class Warrior :public Fighter
{
public:
Warrior(int hp, int mp, int attck) :Fighter(hp, mp, attck) {}
~Warrior() {}
private:
void TakeDamage() override
{
std::cout << "战士拿出锤子后造成伤害" << std::endl;
}
void TakeWeapon() override
{
std::cout << "战士拿出锤子" << std::endl;
}
void PlayAttackAnimation() override
{
std::cout << "播放战士挥舞锤子的动画" << std::endl;
}
};
//是Fighter的角色有 战士 法师 他们拿出武器造成伤害和播放的动画各不相同
class Master :public Fighter
{
public:
Master(int hp, int mp, int attck) :Fighter(hp, mp, attck) {}
~Master() {}
private:
void TakeDamage() override
{
std::cout << "法师拿出法杖后造成伤害" << std::endl;
}
void TakeWeapon() override
{
std::cout << "法师拿出法杖" << std::endl;
}
void PlayAttackAnimation() override
{
std::cout << "播放法师发动魔法的动画" << std::endl;
}
};
int main()
{
std::unique_ptr<Fighter> player1 = std::make_unique<Warrior>(1000, 0, 200);
std::unique_ptr<Fighter> player2 = std::make_unique<Master>(500, 500, 100);
player1->attack();
std::cout << std::endl;
player2->attack();
}
结果: