zoukankan      html  css  js  c++  java
  • 第2章策略模式

    一 概念

    • 策略模式:它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。

    二 UML图

    • Strategy 策略类,定义所有支持的算法的公共接口。
    • Context 上下文,用一个ConcreteStrategy来配置,维护一个对Strategy对象的引用。
    • 具体策略类,封装了具体的算法或行为,继承于Strategy类。

    三 策略模式解析

    • 策略模式是一种定义一系列算法的方法,从概念上来看,所有这些算法完成的都是相同的工作,只是实现不同,它可以以相同的方式调用所有的算法,减少了各种算法类与使用算法类之间的耦合。
    • 策略模式的优点是简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单元单独测试。
    • 策略模式是用来封装算法的,但在实践中,我们发现可以用它来封装几乎任何类型的规则,只要在分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性。

    四 C++实现代码

    #include "pch.h"
    #include <iostream>
    using namespace std;
    //现金收取类的抽象方法  Strategy类
    //定义所有支持的算法的公共接口
    class CashSuper
    {
    public:
    	virtual double acceptCash(double money) = 0;
    };
    //正常收费子类
    class CashNormal : public CashSuper
    {
    public:
    	double acceptCash(double money) override
    	{ 
    		return money;  //正常收费 返回原价即可
    	}
    };
    //打折收费子类
    class CashRebate : public CashSuper
    {
    public:
    	CashRebate(double moneyRebate)
    	{
    		this->_moneyRebate = moneyRebate;
    	}
        double acceptCash(double money) override
    	{
    		return this->_moneyRebate * money;
    	}
    private:
    	double _moneyRebate;
    };
    
    //返利收费子类
    class CashReturn : public CashSuper
    {
    public:
    	CashReturn(double moneyCondition, double moneyReturn)
    		:_moneyCondition(moneyCondition), _meneyReturn(moneyReturn) {}
    	
    	double acceptCash(double money) override
    	{
    		double result = money;
    		if (money > this->_moneyCondition)
    		{
    			result = money - static_cast<double>(money) / this->_moneyCondition * this->_meneyReturn;
    		}
    		return result;
    	}
    private:
    	double _moneyCondition;
    	double _meneyReturn;
    };
    
    class CashContext
    {
    public:
    	//通过构造方法,传入具体的收费策略
    	CashContext(int type)
    	{
    		cs = nullptr;
    		switch (type)
    		{
    		case 1:
    			cs = new CashNormal();
    			break;
    		case 2:
    			cs = new CashReturn(300, 100);
    			break;
    		case 3:
    			cs = new CashRebate(0.8);
    			break;
    		default:
    			break;
    		}
    	}
    	~CashContext()
    	{
    		if (cs != nullptr)
    		{
    			delete cs;
    			this->cs = nullptr;
    		}
    	}
    	//根据收费策略的不同,获得计算结果
    	double GetResult(double money)
    	{
    		return this->cs->acceptCash(money);
    	}
    private:
    	CashSuper* cs;
    };
    
    int main()
    {
    	CashContext* cc = nullptr;
    	cc = new CashContext(1);
    	cout << "正常收费: " << cc->GetResult(400) << endl;
    
    	CashContext* cc2 = nullptr;
    	cc2 = new CashContext(2);
    	cout << "满300减100: " << cc2->GetResult(400) << endl;
    	
    	CashContext* cc3 = nullptr;
    	cc3 = new CashContext(3);
    	cout << "打8折: " << cc3->GetResult(400) << endl;
    	return 0;
    }
    
  • 相关阅读:
    BZOJ2034 【2009国家集训队】最大收益
    「PKUSC2018」最大前缀和
    「PKUSC2018」真实排名
    【FJOI2016】建筑师
    【FJOI2014】最短路径树问题
    【HNOI2007】紧急疏散
    【TJOI2015】线性代数
    【SDOI2017】新生舞会
    POJ2079 Triangle
    【SDOI2011】工作安排
  • 原文地址:https://www.cnblogs.com/Manual-Linux/p/11149304.html
Copyright © 2011-2022 走看看