如果你要实现以下功能:
一个卡牌类,有不同的效果,很自然地可以想到以下实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class BaseCard
{
protected:
std::string name;
std::string description;
size_t id;
dword cost;

public:
void onHandTurnStart();
void onTurnStart();
void onUse();
void onHandTurnEnd();
void onTurnEnd();
dword onAttacked();
void afterAttacked();
dword onAttack();
void afterAttack();

};


class myCard : public BaseCard{
void onUse(){
player.heal(10);
}
}
1
2
3
4
5
6
7
8
9
class player{
public:
void useCard(BaseCard& card){
card.onUse();
}
void TurnStart(BaseCard& card){
card.onTurnStart();
}
}

但是这样,如果要创造更多的不一样的卡牌,就要一直添加Card,同时,如果考虑人物技能,道具能力,也许一个效果要重写多次,所以,完全可以将效果单独拿出来当作新类,然后在对应人物/道具/卡牌中添加不同的效果模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Effect {
public:
virtual void onTurnStart() {};
virtual void onUse() {};
virtual ~Effect() = default;
};

class AEffect : public Effect {
public:
void onUse(){
player.heal(10);
}
};
class CaposEffect : public Effect{
private:
std::vector<std::shared_ptr<Effect>> ce;
public:
void onUse(){
for(auto effect:ce){
effect->onUse();
}
}
void addEffect(std::shared_ptr<Effect>&x){
ce.push_back(x);
}
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class BaseCard
{
protected:
std::string name;
std::string description;
size_t id;
dword cost;
std::shared_ptr<CaposEffect> effects;
public:
virtual void onHandTurnStart(){
effects->onHandTurnStart();
};
virtual void onUse(){
effects->onUse();
};
void addEffect(std::shared_ptr<Effect>&x){
effects.addEffect(x);
}
};


class myCard : public BaseCard{
void onUse(){
player.heal(10);
}
}

这样实现了两种对象之间的解耦,且可以为effect创建effect组,实现多种效果的组合。