策略模式在书中的定义是:它定义了算法家族,分别封转起来,让它们之间可以互相替换,此模式让算法的变化不会影响到使用算法的客户。
创建对象的话让简单工厂模式实现,刚开始总感觉策略模式可有可无,因为按照工厂选择的对象,再调用该对象的方法去实现多态就足够了,为什么还要写一个类来管理具体的方法呢?先实践一下代码,再回头想想吧!!!!
主要实现的类
#include "stdafx.h"
class CashSuper //抽象现金收取类
{
public:
virtual double acceptCash(double money)=0;
};
class CashNormal : CashSuper //正常收费类
{
public:
double acceptCash(double money)
{
return money;
}
};
class CashRebate : CashSuper //折扣类
{
private:
double moneyRebate ;
public:
CashRebate(CString moneyRebate)
{
this->moneyRebate = (double)_wtof(moneyRebate);
}
double acceptCash(double money)
{
return money * moneyRebate;
}
};
class CashReturn : CashSuper //返现类
{
private:
double moneyCondition;
double moneyReturn;
public:
CashReturn(CString moneyCondition,CString moneyReturn)
{
this->moneyCondition = (double)_wtof(moneyCondition);
this->moneyReturn = (double)_wtof(moneyReturn);
}
double acceptCash(double money)
{
double result = money;
if(money >= moneyCondition)
result = money - moneyReturn;
return result;
}
};
/*enum style
{
normal,
discount,
mreturn
};*/
class CashContext
{
CashSuper *cs;
public:
CashContext(int style) //构造的过程中选择相应的类
{
switch(style)
{
case 0:
{
CashNormal *cs0 = new CashNormal();
cs = (CashSuper*)cs0;
break;
}
case 1:
{
CashRebate *cs1 = new CashRebate(_T("0.8"));
cs = (CashSuper*)cs1;
break;
}
case 2:
{
CashReturn *cs2 = new CashReturn(_T("300"),_T("100"));
cs = (CashSuper*)cs2;
break;
}
}
}
double GetResult(double money)
{
return cs->acceptCash(money);
}
};
客户端的代码:
void Cmarket_settlement_systemDlg::OnBnClickedBtnCal()
{
// TODO: 在此添加控件通知处理程序代码
GetDlgItemText(IDC_EDIT_UP,UnitPrice);
GetDlgItemText(IDC_EDIT_N,Number);
double up = (double)_wtof(UnitPrice);
double num = (double)_wtof(Number);
int index = combo.GetCurSel();
double totalPrices = up*num;
CashContext *csuper = new CashContext(index);
totalPrices = csuper->GetResult(totalPrices);
total = total + totalPrices;
CString show ;
show.Format(_T("%f"),totalPrices);
CString record = _T("Unit price:")+UnitPrice + _T(" ")+_T("Number:")+ Number + _T(" ")+_T("sum")+ show;
List.AddString(record);
show.Format(_T("%f"),total);
SUM.SetWindowTextW(show);
}
void Cmarket_settlement_systemDlg::OnBnClickedBtnReset()
{
// TODO: 在此添加控件通知处理程序代码
total = 0.0;
CString end = _T("0.0");
CString end1 = _T("0");
List.ResetContent();
GetDlgItem(IDC_EDIT_UP)->SetWindowTextW(end);
GetDlgItem(IDC_EDIT_N)->SetWindowTextW(end1);
SUM.SetWindowTextW(end);
}
和之前的简单工厂相比,就是多了一个Context的类来调用各种对象的方法。这样是不是说关闭了具体方法调用的过程,让程序员在修改的算法的过程中只需要修改算法类,而不用在调用过程中花费修改的劳动力。
还是要总结一下书本上的说的优点:
1,策略模式定义了一些列的可供重用的算法或行为。继承有助于析取出这些算法中的公共功能。
2,当不同行为堆砌在一个类中时,就很难避免使用条件语句来选择合适的行为。将这些行为封装在一个个独立的strategy类中,可以在使用这些行为的类中消除条件语句。
3,在实践中,我们可以用它来封转几乎任何类型的规则,只要在分析过程中听到需要在不同时间应用的业务规则,就可以考虑使用策略模式处理这种变化。