《Head First设计模式》是一本介绍设计模式的书籍,书中的设计模式主要是用Java语言进行实现,由于本人对C++比较熟悉,因此在阅读这本书籍时,尽自己所能,用C++重新去实现书中所涉及到的设计模式。若有错误或需要进一步讨论之处,望阅览者不吝赐教!
策略模式——定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变换独立于使用算法的客户。
需求:一家公司需要设计一款模拟鸭子游戏的电子软件。游戏中会出现各种鸭子,比如橡皮鸭、诱饵鸭、鸭等,这些鸭子会有不同的行为,比如有的会叫、有的不会叫、有的会飞、有的不会飞等。为了适应不同的鸭子对象和鸭子行为,可以用策略模式进行整个框架的构建。
1、设计一个鸭子类Duck,一个飞行行为接口类(C++里面没有接口的的说法,这里套用Java里的说法,更容易理解)FlyBehavior,一个叫声接口类QuackBehavior,这是第一个设计模式,所以没有考虑周全,将这三个类放到了一个.h文件里;一般而言,应该分开为三个.h文件。Duck.h、Duck.cpp文件具体代码如下:
#pragma once
#include<iostream>
using namespace std;
class FlyBehavior;
class QuackBehavior;
class CDuck
{
public:
CDuck();
~CDuck();
virtual void display() {}
virtual void performFly();
virtual void performQuack();
void setFlyBehavior(FlyBehavior *fb);
void setQuackBehavior(QuackBehavior *qb);
void swim();
protected:
FlyBehavior* flyBehavior;
QuackBehavior* quackBehavior;
};
class FlyBehavior
{
public:
FlyBehavior() {}
~FlyBehavior() {}
virtual void fly() {}
private:
};
class QuackBehavior
{
public:
QuackBehavior() {}
~QuackBehavior() {}
virtual void quack(){}
private:
};
class FlyWithWings:public FlyBehavior //第一个具体飞行行为类
{
public:
FlyWithWings() {}
~FlyWithWings() {}
void fly()
{
cout << "I'm flying!!" << endl;
}
private:
};
class FlyNoWay :public FlyBehavior //第二个具体飞行行为类
{
public:
FlyNoWay() {}
~FlyNoWay() {}
void fly()
{
cout << "I can't fly!!" << endl;
}
private:
};
class FlyRocketPowered:public FlyBehavior //第三个具体飞行行为类
{
public:
FlyRocketPowered(){}
~FlyRocketPowered(){}
void fly()
{
cout << "I'm flying with rocket!!" << endl;
}
private:
};
class Quack:public QuackBehavior //第一个具体叫声类
{
public:
Quack() {}
~Quack() {}
void quack()
{
cout << "Quack" << endl;
}
private:
};
class MuteQuack :public QuackBehavior //第二个具体叫声类
{
public:
MuteQuack() {}
~MuteQuack() {}
void quack()
{
cout << "<< Silence >>" << endl;
}
private:
};
class Squeak :public QuackBehavior //第三个具体叫声类
{
public:
Squeak() {}
~Squeak() {}
void quack()
{
cout << "Squeak" << endl;
}
private:
};
#include "Duck.h"
CDuck::CDuck()
{
}
CDuck::~CDuck()
{
}
void CDuck::performFly()
{
flyBehavior->fly();
}
void CDuck::performQuack()
{
quackBehavior->quack();
}
void CDuck::swim()
{
cout << "All ducks float,even decoys!!" << endl;
}
void CDuck::setFlyBehavior(FlyBehavior* fb)
{
flyBehavior = fb;
}
void CDuck::setQuackBehavior(QuackBehavior *qb)
{
quackBehavior = qb;
}
2、创建两个具体鸭子类:MallardDuck、ModelDuck,MallardDuck.h、MallardDuck.cpp、ModelDuck.h、ModelDuck.cpp文件具体代码如下:
#pragma once
#include "Duck.h"
class CMallardDuck :public CDuck
{
public:
CMallardDuck();
~CMallardDuck();
void display();
};
#include "MallardDuck.h"
CMallardDuck::CMallardDuck()
{
quackBehavior = new Quack();
flyBehavior = new FlyWithWings();
}
CMallardDuck::~CMallardDuck()
{
}
void CMallardDuck::display()
{
cout << "I'm a real Mallard duck!!" << endl;
}
#pragma once
#include "Duck.h"
class CModelDuck :
public CDuck
{
public:
CModelDuck();
~CModelDuck();
void display();
};
#include "ModelDuck.h"
CModelDuck::CModelDuck()
{
flyBehavior = new FlyNoWay();
quackBehavior = new Quack();
}
CModelDuck::~CModelDuck()
{
}
void CModelDuck::display()
{
cout << "I'm a model duck!!" << endl;
}
3、测试代码和结果如下:
/*
策略模式:定义了算法族,分别封装起来,让它们之间可以相互替换,此模式让
算法的变化独立于使用算法的客户
*/
#include "Duck.h"
#include "MallardDuck.h"
#include "ModelDuck.h"
int main()
{
CDuck* mallard = new CMallardDuck();
mallard->performFly();
mallard->performQuack();
CDuck* model = new CModelDuck();
model->performFly();
model->setFlyBehavior(new FlyRocketPowered());
model->performFly();
delete mallard;
delete model;
return 0;
}
在讲述策略模式时,书中涉及到了三个OO原则:
1、封装变化,即将框架中易于变化的部分抽象出来,形成独立的类;
2、多用组合,少用继承,即类与类之间尽量处于合作关系,而不是依赖关系;
3、针对接口编程,不针对具体实现编程,即对接口编程,当需要进行变动时,只需变动接口即可。