设计模式(二)——策略模式

往期地址:


本期主题:

讲解策略模式,并有c++实例



0.设计模式分类

设计模式可按照对对象的操作方式进行分类,一般可分为三类:

  • 创建型设计模式: 提供创建对象的机制,提高已有代码的灵活性,像前面所讲的简单工厂模式便属于创建型设计模式;
  • 结构型设计模式: 将对象和类组成较大的结构,保证结构的灵活和高效;
  • 行为设计模式: 行为模式负责对象间的高效沟通和职责委派;

1.策略模式是什么

策略模式是一种行为设计模式,适用的场景是:

当定义了一系列算法,可以将每种算法放入独立的类中,当算法发生改变时,后续维护可不改变其他代码,让算法相互替换;

2.例子

实现一个超市收费的系统,可以有多种模式收费,正常收费、打八折模式、按照积分计算返利模式…

1 用简单工厂模式有何问题?

使用上一篇文章讲到的简单工厂模式的话,我们会这么设计:

  1. 会创建一个收费抽象类,这是对产品的抽象;
  2. 会有各种各样的产品继承这个收费抽象类,各种各样的产品就是各种的收费算法;
  3. 还有一个收费工厂类,来生产具体的产品

1.UML图:

在这里插入图片描述

2.代码:

代码如下:

#define NORMAL (0)
#define REBATE (1)
//产品,收费抽象类
class Cash_charge
{
public:
	virtual double accpetCash(double money) = 0;
};

//具体产品
//正常收费类,8折收费类,...
class Cash_Normal : public Cash_charge
{
	double accpetCash(double money)
	{
		return money;
	}
};

class Cash_Rebate : public Cash_charge
{
	double accpetCash(double money)
	{
		return 0.8 * money;
	}
};

//工厂,收费工厂类
class Cash_Factory
{
public:
	Cash_charge* Create_Cash_Accpet(char op)
	{
		Cash_charge *cash_charge = NULL;
		// cout << "op : " << op << endl;
		printf("op is %d\r\n", op);
		switch (op)
		{
		case NORMAL:
			cout << "NORMAL" << endl;
			cash_charge = new Cash_Normal();
			break;

		case REBATE:
			cout << "REBATE" << endl;
			cash_charge = new Cash_Rebate();
			break;

		default:
			cout << "defautl" << endl;
			break;
		}

		return cash_charge;
	}
};


int main()
{
	int op = 0;
	float money;
	float result;

	cout << "请输入计费模式: 0代表normal, 1代表8折 :";
	cin >> op;

	cout << "请输入结账金额 :";
	cin >> money;

	Cash_Factory cash_factory_ins;
	Cash_charge *cash_charge_ins = NULL;

	cash_charge_ins = cash_factory_ins.Create_Cash_Accpet(op);

	if (cash_charge_ins == NULL)
	{
		cout << "cash_charge_ins is NULL! \r\n";
		return -1;
	}

	result = cash_charge_ins->accpetCash(money);

	cout << "result : %d" << result << endl;
}

3.问题分析:

这样写还是存在后续的维护问题,假如商场的收费策略经常在变动,那么每次都至少需要改动两个地方:

  1. 需要新增收费类(描述收费策略);
  2. 需要改动工厂生成(简单可理解需要增加switch case)

这样导致每次收费策略变动,都需要重新部署编译工厂类,有什么办法能避免这种情况吗?
这就引出了我们的策略模式;

2 用策略模式来实现

策略模式的实现步骤:

  1. 定义一系列的算法,每种算法是独立的类;
  2. 算法对外的接口抽象,放在策略类中去实现,策略类独立于具体策略;
  3. 关键点: 策略类并不执行策略,而是负责将工作派给已连接的具体策略;

2.1.UML图

在这里插入图片描述

2.2.代码

//产品,收费抽象类
class Cash_charge
{
public:
	virtual double accpetCash(double money) = 0;
};

//具体产品
//正常收费类,8折收费类,...
class Cash_Normal : public Cash_charge
{
	double accpetCash(double money)
	{
		return money;
	}
};

class Cash_Rebate : public Cash_charge
{
	double accpetCash(double money)
	{
		return 0.8 * money;
	}
};


//创建一个策略类,后面更新就不需要再更改策略类,只需要增加新的收费类即可
class Cash_Context
{

    public:
        Cash_charge *cash_charge_ins;

        Cash_Context(Cash_charge *Cash_charge)
        {
            this->cash_charge_ins = Cash_charge;
        }

        double get_result(double money)
        {
            return (this->cash_charge_ins->accpetCash(money));
        }

};


int main()
{
	int op = 0;
	double money;
	double result;

	// cout << "请输入计费模式: 0代表normal, 1代表8折 :";
	// cin >> op;

	cout << "请输入结账金额 :";
	cin >> money;

	Cash_Factory cash_factory_ins;
	Cash_charge *cash_charge_ins = NULL;

    Cash_Context cash_context_ins = Cash_Context(new Cash_Rebate());
    result = cash_context_ins.get_result(money);

	cout << "result : %f" << result << endl;

}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值