第二章 商品促销-策略模式(读书笔记)

来源:互联网 发布:大连淘宝客服在nal 编辑:程序博客网 时间:2024/04/29 13:42

第二章 商品促销-策略模式(读书笔记) 

1.面向对象的编程,并不是类越多越好,类的划分是为了封装,但分类的基础是抽象,具有相同属性和功能的对象的抽象集合才是类。
2.打一折和九折只是形式的不同,抽象分析出来,所有的打折算法都是一样的。所有每一种打折建一个类是非常不合适的。
3.简单工厂模式只是解决对象的创建问题,如果在商品促销系统中,经常性地改打折额度和返利额度,每次维护或扩展收费方式都要改动这个工厂。所有在这个商品促销的系统中简单工厂模式并不是很适用。
4.策略模式(Strategy):它定义了算法家族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。
5.算法本身只是一种策略,最重要的是算法如果是随时都可能互相替换的,这就是变化点。
6.简单工厂模式需要让客户端认识两个类,CashSuper和CashFactory,而策略模式与简单工厂结合的用法,客户端就只需要认识一个类CashContext就可以了,耦合更加降低了。(参照2.6)
7.策略模式的优点是简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单独测试。
8.策略模式中的Context中封装了变化。选择所用具体实现的职责由客户端对象承担,并转给策略模式的Context对象。这样就最大化地减轻了客户端的职责。
9.策略模式就是用来封装算法的,但在实践中,我们发现可以用它来封装几乎任何类型的规则,只要在分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性。

 ---------------------------------------------------------------------------------------------------------------------------------------

2.1商场收银软件的MFC版,先看看简单的界面

程序2.1 最简单的功能就在这两个按钮里面

void CDesignPartern21Dlg::OnBnClickedOk(){// TODO: 在此添加控件通知处理程序代码UINT valA = GetDlgItemInt(IDC_EDIT1, NULL, FALSE);UINT valB = GetDlgItemInt(IDC_EDIT2, NULL, FALSE);SetDlgItemInt(IDC_EDIT3,valA * valB,FALSE);//OnOK();}void CDesignPartern21Dlg::OnBnClickedCancel(){// TODO: 在此添加控件通知处理程序代码SetDlgItemInt(IDC_EDIT1 ,0,FALSE);SetDlgItemInt(IDC_EDIT2 ,0,FALSE);SetDlgItemInt(IDC_EDIT3 ,0,FALSE);//OnCancel();}

 

 ---------------------------------------------------------------------------------------------------------------------------------------

程序2.3 商品促销软件的简单工厂实现

2.3.1 首先是现金类CashSuper.h

#pragma once class CashSuper{public:virtual double AcceptCash(double money) = 0;};class CashNormal :public CashSuper{public://正常收费,按原价返回double AcceptCash(double money){return money;};};class CashRebate :public CashSuper{public:CashRebate(double rebate):m_moneyRebate(1.0){m_moneyRebate = rebate;}//打折后返回double AcceptCash(double money){return money * m_moneyRebate;};private:double m_moneyRebate;};class CashReturn :public CashSuper{public:CashReturn(double returnMoney,double condition):m_moneyReturn(0.0),m_moneyCondition(0.0){m_moneyReturn = returnMoney;m_moneyCondition = condition;}double AcceptCash(double money){double resultMoney = money;if (money > m_moneyCondition){//减去返利值resultMoney = money - (money / m_moneyCondition )* m_moneyReturn;}return resultMoney;};private://返回现金double m_moneyReturn;//返利条件double m_moneyCondition;};


2.3.2 简单工厂类

#pragma once#include "CashSuper.h"typedef enum _Type{eNormal = 0,//正常收费e80Discount,e70Discount,e50Discount,eReturn//满300减100}MyDiscount;class CashFactory{public:static CashSuper* CreateCashAccept(MyDiscount type){CashSuper* cs = NULL;switch (type){case eNormal:cs = new CashNormal();break;case e80Discount:cs = new CashRebate(0.8);break;case e70Discount:cs = new CashRebate(0.7);break;case e50Discount:cs = new CashRebate(0.5);break;case eReturn:cs = new CashReturn(100,300);break;default:cs = new CashNormal();break;}return cs;};};


2.3.3 客户端的调用

#include "stdafx.h"#include "CashFactory.h"#include <iostream>using namespace std;int _tmain(int argc, _TCHAR* argv[]){ double Price; double Num; int selectedIndex; //Price cout << "please Input you Price: " << endl; cin >> Price; //Num cout << "please Input you Num: " << endl; cin >> Num; //Discount cout << "please Input you Discount: "   << "0:正常收费, 1:8折, 2:7折, 3:5折, 4:满300减100" << endl; cin >> selectedIndex; CashSuper* cash = CashFactory::CreateCashAccept((MyDiscount)selectedIndex);  cout << "The total Price is "<< cash->AcceptCash(Price * Num) << endl; return 0;}


 2.3.4 最后实现的UML就是和下面这个图一样

 

 ---------------------------------------------------------------------------------------------------------------------------------------

2.4 在我们用策略模式之前,先看看策略模式的图,比较一下就知道它和简单工厂模式的不同了。

 -----------------------------------------------------------------------------------------------------------------------------------------------------------

2.5 看看这个商品促销系统是如何用上这个模式的。首先是图。

2.5.1 上面的图的代码实现,首先是现金类CashSuper.h

#pragma once class CashSuper{public:virtual double AcceptCash(double money) = 0;};class CashNormal :public CashSuper{public://正常收费,按原价返回double AcceptCash(double money){return money;};};class CashRebate :public CashSuper{public:CashRebate(double rebate):m_moneyRebate(1.0){m_moneyRebate = rebate;}//打折后返回double AcceptCash(double money){return money * m_moneyRebate;};private:double m_moneyRebate;};class CashReturn :public CashSuper{public:CashReturn(double returnMoney,double condition):m_moneyReturn(0.0),m_moneyCondition(0.0){m_moneyReturn = returnMoney;m_moneyCondition = condition;}double AcceptCash(double money){double resultMoney = money;if (money > m_moneyCondition){//减去返利值resultMoney = money - (money / m_moneyCondition )* m_moneyReturn;}return resultMoney;};private://返回现金double m_moneyReturn;//返利条件double m_moneyCondition;};


2.5.2 Context类的实现

#pragma once#include "CashSuper.h"class Context{public:void SetContext(CashSuper* cashsuper){m_pCashSuper = cashsuper;};double GetResult(double money){return m_pCashSuper->AcceptCash(money);};~Context(){if (m_pCashSuper != NULL){delete m_pCashSuper;m_pCashSuper = NULL;}};private:CashSuper* m_pCashSuper;};


2.5.3 客户端的调用方法

#include "stdafx.h"#include <iostream>#include "Context.h"typedef enum _Type{eNormal = 0,//正常收费e80Discount,e70Discount,e50Discount,eReturn//满300减100}MyDiscount;using namespace std;int _tmain(int argc, _TCHAR* argv[]){double Price;double Num;int selectedIndex;//Pricecout << "please Input you Price: " << endl;cin >> Price;//Numcout << "please Input you Num: " << endl;cin >> Num;//Discountcout << "please Input you Discount: " << "0:正常收费, 1:8折, 2:7折, 3:5折, 4:满300减100" << endl;cin >> selectedIndex;Context context;switch (selectedIndex){case eNormal:context.SetContext( new CashNormal());break;case e80Discount:context.SetContext( new CashRebate(0.8));break;case e70Discount:context.SetContext( new CashRebate(0.7));break;case e50Discount:context.SetContext( new CashRebate(0.5));break;case eReturn:context.SetContext( new CashReturn(100, 300));break;default:context.SetContext( new CashNormal());break;}cout << "The total Price is "<< context.GetResult(Num * Price) << endl;return 0;}

---------------------------------------------------------------------------------------------------------------------------------------

2.6 策略模式与简单工厂模式的结合,代码的耦合性进一步降低了。

2.6.1 首先是CashSuper.h,在这里基本没有什么改变

#pragma once class CashSuper{public:virtual double AcceptCash(double money) = 0;};class CashNormal :public CashSuper{public://正常收费,按原价返回double AcceptCash(double money){return money;};};class CashRebate :public CashSuper{public:CashRebate(double rebate):m_moneyRebate(1.0){m_moneyRebate = rebate;}//打折后返回double AcceptCash(double money){return money * m_moneyRebate;};private:double m_moneyRebate;};class CashReturn :public CashSuper{public:CashReturn(double returnMoney,double condition):m_moneyReturn(0.0),m_moneyCondition(0.0){m_moneyReturn = returnMoney;m_moneyCondition = condition;}double AcceptCash(double money){double resultMoney = money;if (money > m_moneyCondition){//减去返利值resultMoney = money - (money / m_moneyCondition )* m_moneyReturn;}return resultMoney;};private://返回现金double m_moneyReturn;//返利条件double m_moneyCondition;};


2.6.2 接下来是CashContext.h,简单工厂就在这里应用。

#pragma once#include "CashSuper.h"typedef enum _Type{eNormal = 0,//正常收费e80Discount,e70Discount,e50Discount,eReturn//满300减100}MyDiscount;class CashContext{public:CashContext(MyDiscount discount):m_pCashSuper(NULL){switch (discount){case eNormal:m_pCashSuper = new CashNormal();break;case e80Discount:m_pCashSuper = new CashRebate(0.8);break;case e70Discount:m_pCashSuper = new CashRebate(0.7);break;case e50Discount:m_pCashSuper = new CashRebate(0.5);break;case eReturn:m_pCashSuper = new CashReturn(100, 300);break;default:m_pCashSuper = new CashNormal();break;}};double GetResult(double money){return m_pCashSuper->AcceptCash(money);};~CashContext(){if (m_pCashSuper != NULL){delete m_pCashSuper;m_pCashSuper = NULL;}};private:CashSuper* m_pCashSuper;};


2.6.3 客户端代码

#include "stdafx.h"#include <iostream>#include "CashContext.h"using namespace std;int _tmain(int argc, _TCHAR* argv[]){double Price;double Num;int selectedIndex;//Pricecout << "please Input you Price: " << endl;cin >> Price;//Numcout << "please Input you Num: " << endl;cin >> Num;//Discountcout << "please Input you Discount: " << "0:正常收费, 1:8折, 2:7折, 3:5折, 4:满300减100" << endl;cin >> selectedIndex;CashContext cash((MyDiscount)selectedIndex);cout << "The total Price is "<< cash.GetResult(Price * Num) << endl;return 0;}



 

 

 

原创粉丝点击