1.简介
在软件工程中,设计模式是一种通用的解决方案,用于解决常见的问题。其中一种非常实用的设计模式是策略模式。策略模式定义了一系列算法,并将每一个算法封装起来,使它们可以互相替换。这样做的好处是算法的变化不会影响到使用算法的客户。
2.通俗讲解
假设我们正在开发一个游戏,玩家可以选择不同的角色,每个角色都有其独特的攻击方式。我们可以使用策略模式来管理这些不同的攻击行为,而不需要修改角色类本身。
3.实战
- 定义接口(或抽象类):创建一个表示所有策略共有的接口。
- 具体策略实现:为每种策略创建一个类,实现上述接口。
- 上下文:创建一个使用策略的类,它通常包含一个指向策略对象的指针,并且提供一个方法让外部代码可以在运行时改变这个策略对象。
3.1.代码
#include <stdio.h>
// 定义策略接口
typedef void (*AttackStrategy)(void);
// 角色结构体
typedef struct {
char name[50];
AttackStrategy attack;
} Character;
// 具体策略实现
void fireball(void) {
printf("Throwing a fireball!\n");
}
void lightning(void) {
printf("Zap! Lightning strike!\n");
}
void swordSwing(void) {
printf("Swinging a mighty sword!\n");
}
// 设置角色攻击方式
void setAttack(Character *character, AttackStrategy attack) {
character->attack = attack;
}
// 角色攻击行为
void performAttack(Character *character) {
printf("%s attacks:\n", character->name);
character->attack();
}
int main() {
// 创建角色
Character wizard, warrior;
// 初始化角色信息
strcpy(wizard.name, "Gandalf");
strcpy(warrior.name, "Aragorn");
// 设置初始攻击方式
setAttack(&wizard, fireball);
setAttack(&warrior, swordSwing);
// 执行攻击
performAttack(&wizard);
performAttack(&warrior);
// 更改攻击方式
setAttack(&wizard, lightning);
setAttack(&warrior, fireball);
// 再次执行攻击
performAttack(&wizard);
performAttack(&warrior);
return 0;
}
3.2.代码解析
- 类型定义:
AttackStrategy
类型定义了一个函数指针,代表攻击行为。 - 角色结构体:
Character
结构体包含角色的名字和一个指向攻击行为函数指针的成员。 - 具体策略实现:
fireball
,lightning
, 和swordSwing
函数分别代表三种不同的攻击行为。 - 设置攻击方式:
setAttack
函数用于更新角色的攻击行为。 - 执行攻击:
performAttack
函数用于展示角色的攻击行为。
3.3.代码运行
Gandalf attacks:
Throwing a fireball!
Aragorn attacks:
Swinging a mighty sword!
Gandalf attacks:
Zap! Lightning strike!
Aragorn attacks:
Throwing a fireball!
3.4.结果分析
- 初始化角色:
- 创建了两个角色:
wizard
和warrior
。 - 分别给这两个角色设置了初始攻击方式:
wizard
使用fireball
,warrior
使用swordSwing
。
- 创建了两个角色:
- 第一次攻击:
wizard
发动攻击,输出"Gandalf attacks: Throwing a fireball!"
。warrior
发动攻击,输出"Aragorn attacks: Swinging a mighty sword!"
。
- 更改攻击方式:
- 更改了
wizard
的攻击方式为lightning
。 - 更改了
warrior
的攻击方式为fireball
。
- 更改了
- 第二次攻击:
wizard
再次发动攻击,这次输出"Gandalf attacks: Zap! Lightning strike!"
。warrior
再次发动攻击,这次输出"Aragorn attacks: Throwing a fireball!"
。
关键点
- 策略模式 在这里被用来封装不同的攻击行为。
- 角色 可以在运行时动态地改变其攻击策略,这使得程序更加灵活。
- 代码的可读性和可扩展性 得到了提高。如果需要添加新的攻击方式,只需要增加新的攻击函数即可,无需修改现有角色的代码。
- 分离关注点:攻击行为的逻辑与角色的其他行为分离,使得代码更易于管理和维护。