[例子向]简单说一下设计模式

最近在看《Head First 设计模式》,学到了一些模式,在这里写些我个人感觉比较适配的例子

1.策略模式

策略模式在游戏中的开发还是挺常见的,比如植物大战僵尸中的向日葵和太阳花,

两者的不同点就是 产出的东西不同。一个是太阳,另一个是金币 或银币。


书中是以一个 鸭子 的例子入手。比如我要设计一个模拟鸭子 软件

先抽象出一个类吧

#ifndef __Duck_H__
#define __Duck_H__

class Duck
{
public:
	virtual void quack();//会呱呱叫
	virtual void swim();//会游泳
	virtual void display();//类似于绘图,目前仅仅是输出到控制台
};
#endif

其他子类继承这个类就可以了

//绿头鸭子
class MallardDuck:public Duck
{
public:
	void display()
	{
		//外观是绿头
	}
};
//红头鸭子
class RedheadDuck:public Duck
{
public:
	void display()
	{
		//外观是红头
	}
};

但如果要加上会飞这个行为 又该怎么办?

简单,在超类加上fly()方法 。修改后的Duck

class Duck
{
public:
	virtual void quack();//会呱呱叫
	virtual void swim();//会游泳
	virtual void display();//类似于绘图,目前仅仅是输出到控制台
	virtual void fly();//会飞
};

好吧,问题来了,如果有 橡皮鸭又该怎么办,无生命会飞的东西(僵尸?飞僵?)

接着用继承,覆盖了fly()方法,让它什么都不做

//橡皮鸭
class RubberDuck:public Duck
{
public:
	virtual void fly()
	{
		//只是覆盖,什么事都不做
	}
};

问题解决了,本节结束。。。。。才怪。

如果要求加入一个木头鸭子(不会叫也不会飞)。按照思路的话我需要覆盖quack()和fly()方法。这样下去无休无止。。。

单纯地这样改变会有几点不好:

1.代码在多个子类中重复

2.很难知道鸭子得全部行为

3.运行时得行为不易改变

4.改变会牵一发而动全身,造成其他鸭子不想要得改变

那么利用接口会如何?

抽象出一个Flyable接口,只有会飞得鸭子才实现此接口。同样,Quackable接口对应会叫的鸭子。

说干就干。看代码

class Duck
{
public:
	virtual void swim();//会游泳
	virtual void display();//类似于绘图,目前仅仅是输出到控制台
};
//----------------------------------Flyable------------------------------
class Flyable
{
public:
	~Flyable(){}
	virtual void fly()=0;
};
//----------------------------------Quackable-------------------------------
class Quackable
{
public:
	~Quackable(){}
	virtual void quack()=0;
};
//绿头鸭子
class MallardDuck:public Duck,public Quackable,public Flyable
{
public:
	void display()
	{
		//外观是绿头
	}
	virtual void fly();
	virtual void quack();
};
//红头鸭子
class RedheadDuck:public Duck,public Quackable,public Flyable
{
public:
	void display()
	{
		//外观是红头
	}
	virtual void fly();
	virtual void quack();
};
//橡皮鸭
class RubberDuck:public Duck
{
public:
	virtual void fly()
	{
		//只是覆盖,什么事都不做
	}
};


绿头鸭和红头鸭只是颜色不同,其他比如飞行,叫声都相同
接口一开始似乎不错,解决了问题,但(c++,java)接口不具有实现代码,所以继承无法达到代码复用

解决:

接下来要用到策略模式了。针对接口编程,而不是针对实现编程

利用接口代表每个行为,而行为得每个实现都将实现其中得一个接口。所以这次鸭子类不会负责实现Fly和Quack,反而是由我们制造一组其他类专门实现FlyBehavior和QuackBehavior “行为”,由行为类而不是Duck类实现行为接口

先看行为类的实现

飞行类

#ifndef __FlyBehavior_H__
#define __FlyBehavior_H__
#include<iostream>
using namespace std;

class FlyBehavior
{
public:
	virtual ~FlyBehavior(){}
	virtual void fly()=0;
};
//---------------------------FlyWithWings--------------------------------------------------
class FlyWithWings:public FlyBehavior
{
public:
	virtual void fly()
	{
		cout<<"我在用翅膀飞行"<<endl;
	}
};
//------------------------FlyNoWay-----------------------------------------------------
class FlyNoWay:public FlyBehavior
{
public:
	virtual void fly()
	{
		cout<<"我不会飞"<<endl;
	}
};
//--------------------------FlyRocketPowered-------------------------------------------------------------
class FlyRocketPowered:public FlyBehavior
{
public:
	virtual void fly()
	{
		cout<<"我正在用火箭飞"<<endl;
	}
};
#endif

#ifndef __QuackBehavior_H__
#define __QuackBehavior_H__
#include<iostream>
using namespace std;

class QuackBehavior
{
public:
	virtual ~QuackBehavior(){}
	virtual void quack()=0;
};
//-----------------------Quack-----------------------------------------------
class Quack:public QuackBehavior
{
public:
	virtual void quack()
	{
		cout<<"呱呱叫"<<endl;
	}
};
//------------------------Squeak-----------------------------------------------
class Squeak:public QuackBehavior
{
public:
	virtual void quack()
	{
		cout<<"吱吱叫"<<endl;
	}
};
//---------------------------MuteQuack-----------------------------------------------------
class MuteQuack:public QuackBehavior
{
public:
	virtual void quack()
	{
		//什么也不做,不会叫
	}
};
#endif

看看新的鸭子类

//Duck.h

#ifndef __Duck_H__
#define __Duck_H__
#include<iostream>
using namespace std;

class QuackBehavior;
class FlyBehavior;

class Duck
{
private:
	FlyBehavior*flyBehavior;
	QuackBehavior*quackBehavior;
public:
	Duck();
	~Duck();
	virtual void swim();//会游泳
	virtual void display();//类似于绘图,目前仅仅是输出到控制台
	void performFly();
	void performQuack();
	void setFlyBehavior(FlyBehavior*behavior);
	void setQuackBehavior(QuackBehavior*behavior);
};
//绿头鸭子
class MallardDuck:public Duck
{
public:
	virtual void display()
	{
		cout<<"绿头鸭子"<<endl;
	}
};
//红头鸭子
class RedheadDuck:public Duck
{
public:
	void display()
	{
		cout<<"红头鸭子"<<endl;
	}
};
//橡皮鸭
class RubberDuck:public Duck
{
public:
	void display()
	{
		cout<<"橡皮鸭子"<<endl;
	}
};

#endif

//Duck.cpp

#include "Duck.h"
#include "FlyBehavior.h"
#include "QuackBehavior.h"
Duck::Duck()
	:flyBehavior(nullptr),quackBehavior(nullptr)
{
}
Duck::~Duck()
{
}
void Duck::swim()
{
	cout<<"我正在游泳"<<endl;
}
void Duck::display()
{
}
void Duck::performFly()
{
	flyBehavior->fly();
}
void Duck::performQuack()
{
	quackBehavior->quack();
}
void Duck::setFlyBehavior(FlyBehavior*behavior)
{
	flyBehavior = behavior;
}
void Duck::setQuackBehavior(QuackBehavior*behavior)
{
	quackBehavior = behavior;
}


再看看main.cpp

#include<iostream>
#include<conio.h>

#include "Duck.h"
#include "FlyBehavior.h"
#include "QuackBehavior.h"

int main()
{
	//绿头鸭子
	Duck*duck = new MallardDuck();
	duck->setFlyBehavior(new FlyWithWings());
	duck->setQuackBehavior(new Quack());
	duck->display();
	duck->performFly();
	duck->performQuack();
	//橡皮鸭
	Duck*duck2 = new RubberDuck();
	duck2->setFlyBehavior(new FlyNoWay());
	duck2->setQuackBehavior(new MuteQuack());
	duck2->display();
	duck2->performFly();
	duck2->performQuack();

	duck2->setFlyBehavior(new FlyRocketPowered());
	duck2->performFly();
	//不至于直接退出
	_getch();

	return 0;
}

测试一下



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值