设计模式 之 策略模式

策略模式(Strategy):将不同的算法封装起来,让它们之间可以相互替换。此模式变化算法,不会影响到使用算法的客户。策略模式结构图如下:
在这里插入图片描述策略模式各类的模板如下:
Strategy类,定义所有支持的算法的公共接口

class Strategy
{
  public:
		virtual void AlgorithmInterface();
};

ConcreteStrategy,封装了具体的算法或行为,继承Strategy

//算法A类
ConcreteStrategyA:Strategy
{
public:
 void AlgorithmInterface();//算法A实现方法
};
//算法B类
ConcreteStrategyB:Strategy
{
public:
 void AlgorithmInterface();//算法B实现方法
};
//算法C类
ConcreteStrategyC:Strategy
{
public:
 void AlgorithmInterface();//算法C实现方法
};

Context,用一个ConcreteStrategy来配置,维护一个对Strategy对象的引用。

//上下文
class Context
{
public:
	Strategy strategy;
	//初始化时,传入具体的(A\B\C)策略对象
	Context(Strategy strategy)
	{
		this.strategy = strategy
	};
	//上下文接口 该接口调用初始化传入的策略对象的算法
	void ContextInterface()
	{
		strategy.AlgorithmInterface();
	}
};

客户端代码

//实例化不同的策略,最终调用不同的算法
void main()
{
	Context *context = NULL;
	context = new Context (new ConcreteStrategyA);
	context.ContextInterface();//调用A算法

  context = new Context (new ConcreteStrategyB);
	context.ContextInterface();//调用B算法
	
	context = new Context (new ConcreteStrategyC);
	context.ContextInterface();//调用C算法
}

注:上述实例化策略时,代码过于重复,复用性不好。可以结合简单工厂模式将实例对象的过程封装起来。

实现商场收银系统,商场具有促销(原价)、打折、返利(例如:满300减10)等活动。不同的活动对应着不同的收银算法。收银系统的类图如下:
在这里插入图片描述

CashSuper.h

//收银基类。属于策略模式:将不同算法封装成类
class CashSuper
{
public:
	//算法虚函数
	virtual double acceptCash(double money) { return 0.0; };
};
//促销类
class CashNormal : public CashSuper
{
public:
	double acceptCash(double)override;
};
//打折类
class CashRebate :public CashSuper
{
public:
	double moneyRebate;
	 CashRebate(double);
	double acceptCash(double)override;
};
//返利类
class CashReturn :public CashSuper
{
public:
	double moneyCondition = 0;
	double moneyReturn = 0;
	double acceptCash(double)override;
	 CashReturn(double, double);
};
//付款类型枚举值
enum CashType
{
	Normal,
	Rebate,
	Return
};
//收银上下文类。属于策略模式,实例不同算法对象,调用相应的算法
class CashContext
{
private:
	CashSuper *cs;
public:
	CashContext(int type)//使用了简单工厂模式,封装不同收银类的实例化
	{
		switch (type) {
		case Normal:
			this->cs = new CashNormal();
			break;
		case Rebate:
			cs = new CashRebate(0.8);
			break;
		case Return:
			cs = new CashReturn(300, 100);
			break;
		}
	};
	double ContextInterface(double money)//调用不同收银实例的算法
	{
		return cs->acceptCash(money);
	};
};

CashSuper.cpp

#include "CashSuper.h"

double CashNormal::acceptCash(double money)
{
	return money;
}
//打折构造函数
 CashRebate::CashRebate(double mr)
{
	moneyRebate = mr;
}
//打折算法重载
double CashRebate::acceptCash(double money)
{
	return money * moneyRebate;
}
//返利构造
 CashReturn::CashReturn(double mc, double mr)
 {
	 moneyCondition = mc;
	 moneyReturn = mr;
 }
 //返利算法重载
double CashReturn::acceptCash(double money)
{
	if (money >= moneyCondition)
	{
		return money - (money / moneyCondition) * moneyReturn;
	}
	return money;
}

main.cpp

#include <iostream>
#include "CashSuper.h"
using namespace std;

int main()
{
  //Normal:原价 Rebate:打8折  Return:满300减100
	CashContext *csuper = new CashContext(Normal);//实例化一个普通收银对象
	cout << csuper->ContextInterface(300)<<endl;//调用普通收银算法
	return 0;
}

运行结果:
实例Normal对象输出:300
实例Rebate对象输出:240
实例Return对象输出:200

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值