针对接口编程,而不是针对实现编程。找出应用中可能需要变化的地方,把它们独立出来,不要和那些需要变化的代码混在一起(把会变化的部分取出并“封装”起来,好让其它部分不受影响)。
在下面的实例中,将fly和quack方法用独立的接口实现,比如FlyBehavior类和QauckBehavior类,所以Duck类不再负责实现Flying和Quacking接口,反而由我们制造一组其它类专门实现FlyBehavior和QuackBehavior,这就称为“行为”类。在该设计中,Duck的子类将使用接口所表示的行为,所以实际的实现不会被绑死在Duck的子类中。
这样的设计,可以让flying和quacking的动作被其它的对象复用,因为这些行为已经与鸭子类无关了,而我们可以新增一些行为,不会影响到既有的行为类,也不会影响“使用”到飞行行为的鸭子类。
#ifndef __STRATEGY_H
#define __STRATEGY_H
#include<iostream>
using namespace std;
class FlyBehavior
{
public:
virtual void fly() = 0;
};
class QuackBehavior
{
public:
virtual void quack() = 0;
};
class FlyWithWings :public FlyBehavior
{
public:
void fly()
{
cout << "I'm flying!!" << endl;
}
};
class FlyNoWay :public FlyBehavior
{
public:
void fly()
{
cout << "I can't fly!!" << endl;
}
};
class Quack :public QuackBehavior
{
public:
void quack()
{
cout << "Quack" << endl;
}
};
class MuteQuack :public QuackBehavior
{
public:
void quack()
{
cout << "Silence" << endl;
}
};
class Squeak :public QuackBehavior
{
public:
void quack()
{
cout << "Squeak" << endl;
}
};
class Duck
{
protected:
FlyBehavior *flyBehavior;
QuackBehavior *quackBehavior;
public:
Duck(){}
void performFly()
{
flyBehavior->fly();
}
void performQuack()
{
quackBehavior->quack();
}
void setFlyBehavior(FlyBehavior* fb)
{
flyBehavior = fb;
}
void setQuackBehavior(QuackBehavior* qb)
{
quackBehavior = qb;
}
};
#endif
#include"strategy.h"
#include<iostream>
using namespace std;
class MallardDuck :public Duck
{
public:
MallardDuck()
{
flyBehavior = new FlyWithWings();
quackBehavior = new Quack();
}
~MallardDuck()
{
delete flyBehavior;
delete quackBehavior;
}
};
int main()
{
Duck *mallardDuck = new MallardDuck();
mallardDuck->performFly();
mallardDuck->performQuack();
delete mallardDuck;
}
如果新增了一个飞行行为
class FlyRocketPowered :public FlyBehavior
{
public:
void fly()
{
cout << "I'm flying with a rocket!" << endl;
}
};
class ModelDuck :public Duck
{
public:
ModelDuck()
{
flyBehavior = new FlyNoWay();
quackBehavior = new Quack();
}
~ModelDuck()
{
delete flyBehavior;
delete quackBehavior;
}
};
int main()
{
Duck* model = new ModelDuck();
model->performFly();
model->performQuack();
model->setFlyBehavior(new FlyRocketPowered());
model->performFly();
delete model;
}