设计原则1:找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。
设计原则2:针对接口编程,而不是针对实现编程。
设计原则3:多用组合,少用继承。
策略模式定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
Java中用的是interface接口。
C++的关键字中并没有interface。interface和class不同,interface仅有接口声明,而且所有的声明默认的访问权限是public而非private(是不是想到了C++中的struct?)
对于C++来说,这相当于抽象类的概念,即其中的成员函数都是纯虚函数,只有声明,没有实现。如:
class abstractClass{ virtual memfunc1() = 0; virtual memfucn2() = 0; };
这是一个用于实现接口的纯抽象类,仅包括纯虚函数的类(一般用作基类,派生类进行具体的实现)。纯虚函数是指用=0标记的虚函数。 抽象类是不能实例化的,换句话说,它只是提供一个interface的功能,它并不实现这些纯虚函数。
正如第一段中所讲,我们可以用C++中的struct来模拟interface,可以采用两种方式:
1. 采用宏定义:#define interface struct;
2. 使用typedef: typedef struct interface。
这样就可以在C++中使用interface了。
定义算法族
#include <iostream>
using namespace std;
class FlyBehavior {
public:
virtual void fly() = 0;
};
class QuackBehavior{
public:
virtual void quack() = 0;
};
实现算法,算法之间可互换
class FlyWithWings :public FlyBehavior {
virtual void fly() {
printf("I'm flying!\n");
}
};
class FlyNoWay :public FlyBehavior {
virtual void fly() {
printf("I can't fly.\n");
}
};
class Quack :public QuackBehavior {
virtual void quack() {
printf("Quack!\n");
}
};
class MuteQuack :public QuackBehavior {
virtual void quack() {
printf("<< Silence >>\n");
}
};
class Squeak :public QuackBehavior {
virtual void quack() {
printf("Squeak\n");
}
};
定义客户,提供接口
class Duck {
public:
virtual void display() = 0;
void performFly() {
pFlyBehavior->fly();
}
void performQuack() {
pQuackBehavior->quack();
}
void swim() {
printf("All ducks float, even decoys!\n");
}
void setFlyBehavior(FlyBehavior* fb) {
pFlyBehavior = fb;
}
void setQuackBehavior(QuackBehavior* qb) {
pQuackBehavior = qb;
}
FlyBehavior* pFlyBehavior;
QuackBehavior *pQuackBehavior;
};
继承
class MallardDuck : public Duck {
public:
MallardDuck() {
pQuackBehavior = new Quack();
pFlyBehavior = new FlyWithWings();
}
void display() {
printf("I'm a real Mallard Duck.\n");
}
};
测试
int main()
{
Duck* mallard = new MallardDuck();
mallard->performQuack();
mallard->performFly();
return 0;
}
如果来了新需求,需要模型鸭用火箭飞行,则添加火箭飞行的实现即可。
class ModelDuck : public Duck {
public:
ModelDuck() {
pQuackBehavior = new Quack();
pFlyBehavior = new FlyNoWay();
}
void display() {
printf("I'm a real Model Duck.\n");
}
};
class FlyRocketPowered : public FlyBehavior {
public:
void fly() {
printf("I'm flying with a rocket!\n");
}
};
测试
int main()
{
Duck* mallard = new MallardDuck();
mallard->performQuack();
mallard->performFly();
Duck* model = new ModelDuck();
model->performFly();
model->setFlyBehavior(new FlyRocketPowered());
model->performFly();
return 0;
}
参考:
1. EricFreeman, FreemanElisabeth, 弗里曼, et al. Head First设计模式[M]. 中国电力出版社, 2007.