C++设计模式——对策略模式的理解

C++设计模式——对策略模式的理解

此文章结合了《head first设计模式》以及其他博主的文章内容,得出自己对策略模式的理解。
引用博客:
继承与策略模式.
C++设计模式——策略模式.

问题的引入

一个游戏公司设计了一个鸭子的基类,其他种类的鸭子都继承该基类。可以呱呱叫,也可以戏水。
图1
现在,这个游戏公司想做出更强大的功能。比如,让鸭子起飞。于是在基类中增加了起飞的行为与实现。
在这里插入图片描述
可是问题来了,在子类中,有一个橡皮鸭。它也在屏幕中飞来飞去。这就不符合现实逻辑。若要让橡皮鸭不能飞行,就会有两个传统的解决方法。
1.使用继承的方法。
(1)第一种继承方式是,这个行为在【所有或大多数】子类的的实现皆相同。那么只需要在父类实现代表【大多数】的行为,并对【个别】行为不同的子类进行【重写】即可。
(2)第二种继承方式是,这个行为对于【大多数】子类都有【不同】的表现,即大多数子类都需要重写它,并且没有太多相同的代码需要复用。 那么可以在父类中只声明接口,而不对其实现;在子类中各自实现这个方法即可。
若使用第一种继承方式。橡皮鸭中实现fly()什么也不做,覆盖掉父类的fly(),该方法虽然让橡皮鸭不能飞,可橡皮鸭中却有了飞这个行为。
若使用第二种继承方式。任意子类的鸭子中都得实现fly()。假设飞行还分为螺旋飞,振翅飞等不同的实现。当有30个子类时,10种是螺旋飞,15种是振翅飞,5种不能飞。不但不能飞的鸭子中却有了飞这个行为,而且还会有大量的重复代码出现。
在这里插入图片描述

2.去掉基类的fly(),子类中能飞的鸭子就写一个fly()函数,不能飞的就不写。
此种方式仍然会产生大量的重复代码。
在这里插入图片描述

问题的解决——策略模式

策略模式定义了算法簇,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
使用策略模式便可将不同的飞行方式封装成不同的类,它们都继承于飞行这个基类。再将飞行的子类传入到鸭子的系统中去,便可以解决上述传统方法带来的问题。
如下为飞行的方式模块,以及生成橡皮鸭不能飞行的方法。

//飞行方式的基类
class FlyBassClass 
{
public:
	virtual void fly() = 0;
};

//飞行方式的子类
class NoFlight  : public FlyBassClass 
{
public:
	void fly() {
		cout<<"不飞行"<<endl;
	}
};

class SpinningFlight : public FlyBassClass 
{
public:
	void fly() {
		cout<<"螺旋飞行"<<endl;
	}
};

class WingsFlight : public FlyBassClass 
{
public:
	void fly() {
		cout<<"振翅飞行"<<endl;
	}
};

//鸭子系统
class Duck
{
public:
	Duck(FlyBassClass *flyWay) 
	{
		//将飞行模块放入
		this->flyWay = flyWay;
	}
	void duckFly() 
	{
		//调用飞行模块的fly(),传入的模块的不同决定飞行方式不同。
		flyWay->fly();
	}

private:
	FlyBassClass *flyWay;
};

int main(int argc, char *argv[])
{
	//实现橡皮鸭不能飞行
    NoFlight  *noFlyWay = new NoFlight;
	Duck *rubberDucks =  new Duck(noFlyWay); 
	rubberDucks->duckFly();
    return 0;
}

若有错误,欢迎指正,非常感谢!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值