显然,鸭子的各个派生类属于 “related classes”,关键就在于“飞”这个行为,如果只是将“飞”的行为,简单划分为“会飞”和“不会飞”,则不使用设计模式完全可以
如果“飞行方式”,随着派生类的增多,至少会有几十种;或者视“飞行方式”为一种算法,以后还会不断改进;再或“飞行方式”作为封装算法,提供给第三方使用。
那么此时,设计模式的价值就体现出来了 -- 易复用,易扩展,易维护。
而第 4) 种适用情景,多见于重构之中 -- "Replace Type Code with State/Strategy"
2 设计原则
在引出策略模式之前,先来看面向对象的三个设计原则
1) 隔离变化:identify what varies and separate them from what stays the same
Duck 基类中, 很明显“飞行方式“是变化的,于是把 fly 择出来,和剩余不变的分隔开来
2) 编程到接口:program to an interface, not an implementation
分出 fly 之后,将其封装为一个接口,里面实现各种不同的“飞行方式” (一系列”算法“),添加或修改算法都在这个接口里面进行。“接口”对应于 C++ 便是抽象基类,
即将“飞行方式”封装为 FlyBehavior 类,该类中声明 fly 成员函数为纯虚函数
class FlyBehavior {
public:
virtual void fly() = 0;
};
class FlyWithWings : public FlyBehavior {
public:
virtual void fly();
};
class FlyNoWay ...class FlyWithRocket ...
具体实现各种不同的算法 -- “飞行方式”,如下所示:
void FlyWithWings::fly() { std::cout << "I am flying !" << std::endl; }
void FlyNoWay::fly() { std::cout << "I cannot fly !" << std::endl; }
void FlyWithRocket::fly() { std::cout << "I am flying with a rocket !" << std::endl; }
3) 复合 > 继承:favor composition (has-a) over inheritance (is-a)
<Effective C++> 条款 32 中提到,公有继承即是“is-a”,而条款 38 则提及 Composition (复合或组合) 的一个含义是 “has-a”。因此,可以在 Duck 基类中,










