设计模式(三)
常见的行为型模式
1.模板方法模式: 模版模式定义了一个操作的整体流程, 子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤.
假设我们有一个制作饮料的算法框架,这个算法包括以下步骤:
- 烧水
- 泡制饮料(如泡茶或冲咖啡)
- 倒入杯中
- 添加调料
制作咖啡 和 茶.
cpp
#include <iostream>
using namespace std;
// 模板方法模式
class TemplatePattern {
public:
// 烧水
virtual void HeatWater() = 0;
// 冲泡
virtual void Brew() = 0;
// 倒入杯中
virtual void PutCup() = 0;
// 加料
virtual void AddFeed() = 0;
void make() {
HeatWater();
Brew();
PutCup();
AddFeed();
}
virtual ~TemplatePattern() { }
};
class DrinkTea :public TemplatePattern {
public:
DrinkTea( ){ }
virtual ~DrinkTea() { }
// 烧水
virtual void HeatWater() {
cout << "烧矿泉水" << endl;
}
// 冲泡
virtual void Brew() {
cout << "冲泡茶" << endl;
}
// 倒入杯中
virtual void PutCup() {
cout << "将茶倒入杯中" << endl;
}
// 加料
virtual void AddFeed() {
cout << "加入柠檬" << endl;
}
};
int main() {
DrinkTea* tea = new DrinkTea;
tea->make();
return 0;
}
2.策略模式:定义了一系列算法 ,将每一个算法都封装,并且这些算法之间可以相互替代.
具体实现
cpp
#include <iostream>
using namespace std;
// 武器策略
class WeaponStrategy {
public:
virtual void UseWeapon() = 0;
virtual ~WeaponStrategy( ) { }
};
// 具体的武器(小刀)
class Kinfe :public WeaponStrategy {
public:
virtual void UseWeapon() {
cout << "user kinfe" << endl;
}
};
// 具体的武器(ak47)
class AK47 :public WeaponStrategy {
public:
virtual void UseWeapon() {
cout << "user ak47" << endl;
}
};
// 小人
class Character {
public:
Character( ) {
mWeapon_ = nullptr;
}
// 设置武器
void SetWeapon( WeaponStrategy* mWeapon ) {
mWeapon_ = mWeapon;
}
// 使用武器
void Use_of_weapons( ) {
mWeapon_->UseWeapon();
}
private:
WeaponStrategy* mWeapon_ ;
};
void test1() {
Character* character = new Character;
WeaponStrategy* kinfe = new Kinfe;
WeaponStrategy* ak47 = new AK47;
character->SetWeapon(kinfe);
// 小人使用武器
character->Use_of_weapons();
character->SetWeapon(ak47);
// 小人使用武器
character->Use_of_weapons();
}
int main() {
test1();
return 0;
}
3.观察者模式: 描述对象之间的依赖关系 , 一个对象的状态发生改变 ,会自动通知其他对象,使其他的对象做出反应.
我们可以想象红绿灯的场景 ,当红灯时( 相当于是红绿灯发出的一个信号 ),汽车需要停下等待 .当出现绿灯时,汽车可以正常行驶了.
在这个场景中 , 红绿灯是观察目标 ,汽车是观察者.
具体代码实现:
1.三个英雄打一个BOSS, 处于攻击状态
2.当BOSS死亡使 , 停止攻击( 这里我们假设BOSS不还手 )
cpp
#include <iostream>
#include <list>
using namespace std;
class AbstractorBoss;
// 英雄状态
enum class State {
// 攻击状态
ATTACT_ATATE ,
// 停止攻击状态
STOP_ATTACK_SATATE
};
// 英雄抽象类
class AbstractorHero {
public:
virtual void Update() = 0;
virtual void AttackBoss() = 0;
virtual void ShowState() = 0;
virtual ~AbstractorHero() { }
protected:
int attack_; // 英雄的攻击力
AbstractorBoss *boss_; //
State state_; // 英雄状态
};
class AbstractorBoss {
public:
virtual void AddHero( AbstractorHero* hero ) = 0 ;
virtual void DeleteHero(AbstractorHero* hero ) = 0 ;
virtual void Notify( ) = 0 ;
virtual ~AbstractorBoss() { }
public:
list<AbstractorHero*>heros_; // 英雄列表
int blood_; // 血量
};
// 具体的boss
class Boss :public AbstractorBoss {
public:
Boss(int blood) {
blood_ = blood;
}
virtual void AddHero(AbstractorHero* hero) {
// it -> list<AbstractorHero*>::itreator
for (auto it : heros_) { // 在增加英雄的时候,判断英雄是否已经存在
if (it == hero) {
return;
}
}
heros_.push_back(hero);
}
virtual void DeleteHero(AbstractorHero* hero) {
for (auto it : heros_) { // 在删除英雄的时候,判断英雄是否已经存在
if (it == hero) {
heros_.remove(hero);
}
}
}
virtual void Notify() {
if (blood_ <= 1) {
cout << "boss 死亡,英雄停止攻击" << endl;
for (auto it : heros_) {
it->Update();
}
}
}
};
// 英雄A
class HeroA :public AbstractorHero {
public:
HeroA(int attack , AbstractorBoss* boss) : AbstractorHero( ){
this->attack_ = attack;
boss_ = boss;
state_ = State::ATTACT_ATATE;
}
virtual void Update() {
state_ = State::STOP_ATTACK_SATATE;
}
virtual void AttackBoss() {
boss_->blood_ -= attack_;
}
virtual void ShowState() {
if (state_ == State::ATTACT_ATATE) {
cout << "英雄处于攻击状态" << endl;
}
else if (state_ == State::STOP_ATTACK_SATATE) {
cout << "英雄处于停止攻击状态" << endl;
}
}
};
void test2() {
// 创建一个boss
AbstractorBoss* boss = new Boss(100);
// 创建两个英雄
AbstractorHero *hero1 = new HeroA( 50, boss );
AbstractorHero* hero2 = new HeroA( 60, boss );
boss->AddHero(hero1);
boss->AddHero(hero2);
hero1->AttackBoss();
hero2->AttackBoss();
boss->Notify();
// 输出英雄的状态
hero1->ShowState();
hero2->ShowState();
}
int main() {
//HeroA A(100);
test2();
return 0;
}