策略模式
策略模式,在HeadFirst 中是这样定义的,它定义了算法族,分别封装起来,他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
第一章中一共讲到了三种设计策略:
1.找出应用中的可能需要变化的地方,把他们独立出来,不要和那些需要变化的代码混在一起
2.针对接口编程,而不是针对实现编程。
对此我的理解是,应当实现动态的绑定,而不是静态的实现
3.多用组合,少用继承
Headfirst 中举例是蜂鸣器的设计实现,将两个动态变化的动作(fly和quack),给拿出来作为两个接口动作来实现:
c++ 实现代码如下:
using namespace std;
/****************************************************************
*fly behavior
***************************************************************/
class FlyBehavior{//fly abtract class
public:
FlyBehavior(){}
virtual void fly()=0;
virtual ~FlyBehavior(){}
};
//duck without wings behavior
class FlyWithWings :public FlyBehavior{
public:
FlyWithWings(){}
void fly(){
cout<<"I'm flying"<<endl;
}
~FlyWithWings(){}
};
//duck can't fly
class FlyNoWay:public FlyBehavior
{
public:
FlyNoWay(){}
void fly(){
cout<<"I can't fly"<<endl;
}
~FlyNoWay(){}
};
//duck can fly with the help rocket
class FlyRocketPowered:public FlyBehavior{
public:
FlyRocketPowered(){}
void fly(){
cout<<"I'm flying with a rocket"<<endl;
}
~FlyRocketPowered(){}
};
/************************************************************
* duck quack
*************************************************************/
class QuackBehavior{//abtract class
public:
QuackBehavior(){}
virtual void Quack()=0;
~QuackBehavior(){}
};
//quck can quack
class DuckQuack:public QuackBehavior{
public:
DuckQuack(){}
void Quack(){
cout<<"Quack!"<<endl;
}
~DuckQuack(){}
};
//duck Mute
class MuteQuack:public QuackBehavior{
public:
MuteQuack(){}
void Quack(){
cout<<"Mute"<<endl;
}
~MuteQuack(){}
};
//duck Squeak
class Squeak:public QuackBehavior{
public:
Squeak(){}
void Quack(){
cout<<"Squeak"<<endl;
}
~Squeak(){}
};
class Duck{
public:
FlyBehavior *flybehavior;
QuackBehavior *quackbehavior;
Duck(){}
virtual void display()=0;
void performfly(){
flybehavior->fly();
}
void performquack(){
quackbehavior->Quack();
}
void setFlyBehavior(FlyBehavior *fb){
flybehavior=fb;
}
void setQuackBehavior(QuackBehavior *qb){
quackbehavior=qb;
}
void swim(){
cout<<"all ducks can float"<<endl;
}
~Duck(){}
};
//the first duck
class MallardDuck:public Duck{
public:
MallardDuck(){
quackbehavior =new DuckQuack();
flybehavior =new FlyWithWings();
}
void display(){
cout<<"I'm a real Mallard Duck"<<endl;
}
~MallardDuck(){}
};
//the second duck
class ModelDuck:public Duck{
public:
ModelDuck(){
flybehavior=new FlyNoWay();
quackbehavior=new DuckQuack();
}
void display(){
cout<<"I'm a ModelDuck!"<<endl;
}
~ModelDuck(){};
};
//test in main
int main()
{
/*****************************************
*test case1 dynamic binding
******************************************/
Duck *mallard=new MallardDuck();
mallard->display();
mallard->swim();
mallard->performquack();
mallard->performfly();
cout<<endl<<endl<<endl;
cout<<"the other case will begin"<<endl<<endl<<endl;
/**************************************************
*test case2 dynamic change the duck fly way
***************************************************/
Duck *model=new ModelDuck();
model->performfly();
model->setFlyBehavior(new FlyRocketPowered());
model->performfly();
return 0;
}