0
点赞
收藏
分享

微信扫一扫

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

刘员外__ 2022-03-21 阅读 118

往期地址:

  • 设计模式(一)——简单工厂模式

本期主题:

讲解策略模式,并有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 条评论