您的位置:首页 > 编程语言 > C语言/C++

Head First设计模式C++实现--第一章:策略模式

2014-06-21 22:51 441 查看

策略模式

一、问题的提出

公司现有一个鸭子基类,其他类继承此类:





现在需要让鸭子能飞,则由继承很容易想到了在基类Duck中添加一个fly()方法,让所有继承此类的子类都有fly的功能:

但问题1:并非所有鸭子都能飞,在基类中添加新行为,使得某些不合适该行为的子类也具有该行为(比如:会飞的橡皮鸭)。对代码所做的局部修改,影响层面不只是局部。
当然,可以通过复写fly()方法来解决问题1, 让它什么都不做,但是如果继续有新的需求又要进行重写,代码无法复用且不好管理。

二、设计模式的解决方案

设计原则:找出应用中可能需要变化之处,把他们独立出来,不要和那些不需变化的代码混在一起。

1、分开变化和不会变化的部分

由于Duck类中的quack()和fly()会随着鸭子的不同,行为不同,因此是变化的部分,将它们从Duck中独立出来,建立一组新类来代表每个行为。

2、设计鸭子行为

针对接口编程,而不是针对实现编程。

利用接口代表每个行为,如:FlyBehavior和QuackBehavior两个接口,而行为的每个实现都将实现其中的一个接口。





3、实现鸭子行为

这样的设计,可以让飞行和叫的动作被其他对象复用,因为这些行为被独立出来,与Duck类无关了,具有了复用的好处,却没有继承带来的包袱。

4、整合鸭子的行为

经过以上的设计,整合后的类图:



5、C++代码实现

头文件:

#ifndef DUCK__H
#define DUCK__H

//飞行行为抽象类
class FlyBehavior
{
public:
	virtual void fly() = 0;
};
//能飞行具体类
class FlyWithWings : public FlyBehavior
{
public:
	void fly();
};
//不能飞行具体类
class FlyNoWay : public FlyBehavior
{
public:
	void fly();
};

//叫声行为抽象类
class QuackBehavior
{
public:
	virtual void quack() = 0;
};
//叫声具体类“Quack”
class Quack : public QuackBehavior
{
public:
	void quack();
};
//叫声具体类“Quiet”
class MuteQuack : public QuackBehavior
{
public:
	void quack();
};
//叫声具体类“Squeak”
class Squeak : public QuackBehavior
{
public:
	void quack();
};

//基类
class Duck
{
public:
	virtual void performFly();
	virtual void performQuack();
//基类的指针,用于动态绑定确定动作的行为
	FlyBehavior* flyBehavior;
	QuackBehavior* quackBehavior;
};

class MallardDuck : public Duck
{
public:
	MallardDuck();
	~MallardDuck();
	void display();
};

#endif


cpp文件:
#include "Duck.h"
#include<iostream>

void FlyWithWings::fly()
{
	std::cout<<"I'm flying"<<std::endl;
}

void FlyNoWay::fly()
{
	std::cout<<"I can't fly"<<std::endl;
}

void Quack::quack()
{
	std::cout<<"Quack"<<std::endl;
}

void MuteQuack::quack()
{
	std::cout<<"Silence"<<std::endl;
}

void Squeak::quack()
{
	std::cout<<"Squeak"<<std::endl;
}

void Duck::performFly()
{
	flyBehavior->fly();
}

void Duck::performQuack()
{
	quackBehavior->quack();
}

//初始化,用能飞行的具体类和“Quack”叫声的具体类初始化指针,
MallardDuck::MallardDuck()
{
	flyBehavior = new FlyWithWings();
	quackBehavior = new Quack();
}
//析构
MallardDuck::~MallardDuck()
{
	if(NULL != flyBehavior)
		delete flyBehavior;
	if(NULL != quackBehavior)
		delete quackBehavior;
}


策略模式:定义了算法簇,分别封装起来,让他们之间可以相互替换,此模式让算法的变化独立于使用算法的客户。

三、总结

1.对C++的动态绑定理解清楚,这是多态的前提(基类的指针或引用指向子类对象)

2.多用类来进行提取可变操作,尽量让可变的代码分离出来。

3.个人感觉类似乎有点多。。

4.希望能和有缘人多多交流,虽然只是很基础,但是本人领悟不够好,这个学习方式貌似比较适合偶。。。望有缘人看到多多交流。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: