第2章 策略模式
商场收银软件
简单工厂模式
#include <iostream>
using namespace std;
//现金收费抽象类
class AbstractCashSuper {
public:
virtual double acceptCash(double money) = 0;
};
class CashNormal :public AbstractCashSuper {
public:
double acceptCash(double money) {
return money;
}
};
class CashRebate :public AbstractCashSuper {
private:
double moneyRebate {1};
public:
CashRebate(double rebate) {
moneyRebate = rebate;
}
double acceptCash(double money) {
return money*moneyRebate;
}
};
class CashReturn :public AbstractCashSuper {
private:
double moneyCondition = 0;
double moneyReturn = 0.0;
public:
CashReturn(double condMoney, double retMoney) {
moneyCondition = condMoney;
moneyReturn = retMoney;
}
double acceptCash(double money) {
return money - int(money / moneyCondition) * moneyReturn;
}
};
/*
若增加新的商场促销手段,满100积分10点时,则需增加一个新的类,继承CashSuper,
在CashFactory增加条件分支,客服界面也需要稍微改动
*/
class CashFactory {
public:
static AbstractCashSuper* createCash(int type) {
if (type == 1)
return new CashNormal;
else if (type == 2)
return new CashRebate(0.8); //更改打折初始值
else if (type == 3)
return new CashReturn(300, 100); //更改满减初始值
else
return NULL;
}
};
void test01(double totalprice, int type) {
CashFactory factory;
AbstractCashSuper* absCashSuper = factory.createCash(type);
cout << "应收金额为:" << absCashSuper->acceptCash(totalprice) << endl;
}
int main() {
double price = 0;
cout << "请输入商品价格:";
cin >> price;
int number = 0;
cout << "请输入商品数量:";
cin >> number;
int cashType;
cout << "请选择活动模式(1.正常,2.打8折,3.满300减100):" ;
cin >> cashType;
double totalPrice = 0;
totalPrice = price * number;
test01(totalPrice, cashType);
return 0;
}
策略模式
策略模式(Strategy):它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。【DP】
商场收银时如何促销,用打折还是返利,其实都是一些算法,用工厂来生成算法对象,这没有错,但算法本身只是一种策略,最重要的是随时都有可能互相替换的,这就是变化点,而封装变化点是我们面向对象的一种很重要的思维方式。
CashSuper就是抽象策略,而正常收费CashNormal、打折CashRebate和返利CashReturn就是三个具体策略,也就是策略模式中说的具体算法
//策略模式
class CashContext {
public:
CashContext(AbstractCashSuper* abs) {
mCashSuper = abs;
}
double getResult(double money) {
return mCashSuper->acceptCash(money);
}
private:
AbstractCashSuper* mCashSuper;
};
void test01(double totalprice, int type) {
AbstractCashSuper* abs = NULL;
CashContext* mcs = NULL;
if (type == 1){
abs = new CashNormal;
mcs = new CashContext(abs);
}
else if (type == 2) {
abs = new CashRebate(0.8);
mcs = new CashContext(abs);
}
else if (type == 3) {
abs = new CashReturn(300, 100);
mcs = new CashContext(abs);
}
cout << "应收金额为:" << mcs->getResult(totalprice) << endl;
delete mcs;
delete abs;
}
策略模式Pro
//策略模式Pro
class CashContextPro {
public:
CashContextPro(int type){
if (type == 1)
mCashSuper = new CashNormal;
else if (type == 2)
mCashSuper = new CashRebate(0.8);
else if (type == 3)
mCashSuper = new CashReturn(300, 100);
}
double getResult(double money) {
return mCashSuper->acceptCash(money);
}
private:
AbstractCashSuper* mCashSuper = NULL;
};
void test01(double totalprice, int type) {
CashContextPro* ccp = new CashContextPro(type);
cout << "应收金额为:" << ccp->getResult(totalprice) << endl;
delete ccp;
}
改进后的策略模式还是存在不足,比如,需要增加一种算法,“满200送50”,就必须更改CashContextPro中的if else 代码。
还可以用到反射技术进行优化。