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

本文介绍了设计模式中的策略模式,通过C++详细讲解如何将变化部分与不变部分分离,设计并实现鸭子行为。文章涵盖问题提出、解决方案、C++代码实现及学习感悟,强调了动态绑定和多态的重要性。
摘要由CSDN通过智能技术生成

策略模式

一、问题的提出

公司现有一个鸭子基类,其他类继承此类:
          
现在需要让鸭子能飞,则由继承很容易想到了在基类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.希望能和有缘人多多交流,虽然只是很基础,但是本人领悟不够好,这个学习方式貌似比较适合偶。。。望有缘人看到多多交流。


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值