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

    面向对象的编程,并不是类越多越好,类的划分是为了封装,但分类的基础是抽象,具有相同属性和功能的对象的抽象集合才是类。

    商场收银软件的简单工厂实现

    图片

    商场促销程序简单工厂UML图
     
    #include<iostream>
    
    using namespace std;
    
    class CashSuper
    {
    public:
    	virtual double acceptCash(double money) = 0;
    };
    
    class CashNormal : public CashSuper
    {
    public:
    	double acceptCash(double money)
    	{
    		return money;
    	}
    };
    
    class CashRebate : public CashSuper
    {
    private:
    	double moneyRebate;
    
    public:
    	CashRebate(double moneyRebate_t) : moneyRebate(moneyRebate_t) {}
    
    	double acceptCash(double money)
    	{
    		return money * moneyRebate;
    	}
    };
    
    class CashReturn : public CashSuper
    {
    private:
    	double moneyCondition;
    	double moneyReturn;
    
    public:
    	CashReturn(double moneyCondition_t, double moneyReturn_t) : moneyCondition(moneyCondition_t), moneyReturn(moneyReturn_t) {}
    
    	double acceptCash(double money)
    	{
    		double result = money;
    		if (money >= moneyCondition)
    			result = money = (money - moneyCondition)*moneyReturn;
    
    		return result;
    	}
    };
    
    class CashFactory
    {
    public:
    	static CashSuper* createCashAccept(int type)
    	{
    		CashSuper *cs = nullptr;
    		switch (type)
    		{
    		case 1:
    			cs = new CashNormal;
    			break;
    		case 2:
    			cs = new CashRebate(0.8);
    			break;
    		case 3:
    			cs = new CashReturn(300, 100);
    			break;
    		}
    
    		return cs;
    	}
    };
    
    int main()
    {
    	double price, num;
    	cout << "请输入单价和数量:" << endl;
    	cin >> price >> num;
    	double total = price * num;
    	cout << "1.正常收费" << endl;
    	cout<<"2.打8折"<<endl; 
    	cout<<"3.满300返100"<<endl;
    	cout << "请输入促销条件前的数字序号: " << endl;
    	int type;
    	cin >> type;
    	CashSuper *cs = CashFactory::createCashAccept(type);
    	double result = cs->acceptCash(total);
    	cout << result << endl;
    	
    
    	system("pause");
    	return 0;
    }
    
    

    由于工厂本身包括了所有的收费方式,商场是可能经常性的更改打折额度和返利额度,每次维护或者扩展收费方式都要改动这个工厂,以致代码需要重新编译部署,所以用它不是最好的办法。

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

    图片

    策略模式结构图

    基本代码实现

    #include<iostream>
    #include<string>
    
    using namespace std;
    
    //Strategy类,定义所有支持的算法的公共接口
    class Strategy
    {
    public:
    	virtual void AlgorithmInterface() = 0;
    };
    
    //ConcreteStrategy,封装了具体的算法或行为,继承于Strategy
    class ConcreteStrategyA :public Strategy
    {
    public:
    	void AlgorithmInterface()
    	{
    		cout << "算法A实现" << endl;
    	}
    };
    
    class ConcreteStrategyB :public Strategy
    {
    public:
    	void AlgorithmInterface()
    	{
    		cout << "算法B实现" << endl;
    	}
    };
    
    class ConcreteStrategyC :public Strategy
    {
    public:
    	void AlgorithmInterface()
    	{
    		cout << "算法C实现" << endl;
    	}
    };
    
    //Context,用一个ConcreteStrategy来配置,维护一个队Strategy对象的引用
    class Context
    {
    private:
    	Strategy *strategy;
    public:
    	Context(Strategy *strategy_t)   //初始化时,传入具体的策略
    	{
    		strategy = strategy_t;
    	}
    
    	void ContextInterface()        //根据具体的策略对象,调用其算法的方法
    	{
    		strategy->AlgorithmInterface();
    	}
    
    };
    
    int main()
    {
    	Context *context = nullptr;
    
    	context = new Context(new ConcreteStrategyA());
    	context->ContextInterface();
    	
    	context = new Context(new ConcreteStrategyB());
    	context->ContextInterface();
    
    	context = new Context(new ConcreteStrategyC());
    	context->ContextInterface();
    
    	system("pause");
    	return 0;
    }
    
    

    商场收银软件的策略模式加简单工厂实现

    图片

    商场促销程序策略模式UML图
    #include<iostream>
    
    using namespace std;
    
    /*定义所有支持的算法的公共接口*/
    class CashSuper
    {
    public:
    	virtual double acceptCash(double money) = 0;
    };
    
    /*封装了具体的算法或行为*/
    class CashNormal : public CashSuper
    {
    public:
        /*具体算法的实现*/
    	double acceptCash(double money)
    	{
    		return money;
    	}
    };
    
    class CashRebate : public CashSuper
    {
    private:
    	double moneyRebate;
    
    public:
    	CashRebate(double moneyRebate_t) : moneyRebate(moneyRebate_t) {}
    
    	double acceptCash(double money)
    	{
    		return money * moneyRebate;
    	}
    };
    
    class CashReturn : public CashSuper
    {
    private:
    	double moneyCondition;
    	double moneyReturn;
    
    public:
    	CashReturn(double moneyCondition_t, double moneyReturn_t) : moneyCondition(moneyCondition_t), moneyReturn(moneyReturn_t) {}
    
    	double acceptCash(double money)
    	{
    		double result = money;
    		if (money >= moneyCondition)
    			result = money = (money - moneyCondition)*moneyReturn;
    
    		return result;
    	}
    };
    
    /*用一个ConcreteStrategy来配置,维护一个对Strategy对象的引用*/
    class CashContext
    {
    private:
    	CashSuper *cs = nullptr;
    	int type;
    
    public:
        /*集合了简单工厂模式,初始化时,传入具体的策略对象*/
    	CashContext(int t): type(t)
    	{
    		switch(type)
    		{
    		case 1:
    			cs = new CashNormal;
    			break;
    		case 2:
    			cs = new CashRebate(0.8);
    			break;
    		case 3:
    			cs = new CashReturn(300, 100);
    			break;
    		}
    	}
        
        /*上下文接口,根据具体的策略对象,调用其算法的方法*/
    	double GetResult(double money)
    	{
    		return cs->acceptCash(money);
    	}
    
    };
    
    int main()
    {
    	double price, num;
    	cout << "请输入单价和数量:" << endl;
    	cin >> price >> num;
    	double total = price * num;
    	cout << "1.正常收费" << endl;
    	cout<<"2.打8折"<<endl; 
    	cout<<"3.满300返100"<<endl;
    	cout << "请输入促销条件前的数字序号: " << endl;
    	int type;
    	cin >> type;
    	CashContext *csuper = new CashContext(type);
    	double result = csuper->GetResult(total);
    	cout << result << endl;
    	
    
    	system("pause");
    	return 0;
    }
    
    

    简单工厂模式我们需要让客户端认识两个类,CashSuper和CashFactory,而策略模式与简单工厂模式结合的用法,客户端只需要认识一个类CashContext就可以了,耦合更加降低。

    策略模式解析

    策略模式是一种定义一系列算法的方法,从概念上来看,所有这些算法完成的都是相同的工作,只是实现不同,他可以以相同的方式调用所有的算法,减少了各种算法类与使用算法类之间的耦合。
    策略模式的Strategy类层次为Context定义了一系列的可供重用的算法或行为。继承有助于析取出这些算法的公共功能。
    另一个策略模式的优点是简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单独测试。
    当不同的行为堆砌在一个类中时,就很难避免使用条件语句来选择合适的行为。将这些行为封装在一个个独立的Strategy类中,可以在使用这些行为的类中消除条件语句。
    策略模式就是用来封装算法的,但在实践中,我们发现可以用它来封装几乎任何类型的规则,只要在分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性。

  • 相关阅读:
    c++ *.h和*.cpp在编译中的作用
    test
    DOM Tree
    SecureCRT
    趣味盒1
    数据结构笔试:前缀表达式|后缀表达式
    Shell 文件包含
    Shell 输入/输出重定向
    Shell 函数
    Shell 流程控制
  • 原文地址:https://www.cnblogs.com/wfcg165/p/11982307.html
Copyright © 2011-2022 走看看