Demo with Mixture DesignPattern
混合模式的使用Demo
之前把主要的设计模式都学了一遍,但是在实际项目中,经常是几个模式一同使用。
我找了一个使用混合模式的场景,并用C++进行实现。
###这个场景主要是使用工厂模式+策略模式+门面模式
场景:设计一个交易系统中的子模块——扣款子模块
扣款子模块中主要包括两部分:
1.IC卡类和交易信息类
其中IC卡中包括两种金额:固定金额和自由金额;交易信息类负责记录每一笔交易。
2.扣款策略类
####扣款策略有以下两种:
a. IC卡固定金额 = IC卡现有固定金额-交易金额/2
IC卡自由金额 = IC卡自由金额-交易金额/2
b. 全部消费从IC卡自由金额中扣除
#include
#include
using namespace std;
class Card
{
private:
string No;
int steadyMoney; //卡内固定交易金额
int freeMoney; //卡内自由交易金额
public:
string getNo() {return No;}
void setNo(string no) {No = no;}
int getSteadyMoney() {return steadyMoney;}
void setSteadyMoney(int steadyMoney) {this->steadyMoney = steadyMoney;}
int getFreeMoney() { return freeMoney; }
void setFreeMoney(int freeMoney) { this->freeMoney = freeMoney;}
};
class Trade
{
private:
string tradeNo;
int mount; //交易金额
public:
string getTradeNo() { return tradeNo; }
void setTradeNo(string tradeNo) { this->tradeNo = tradeNo; }
int getMount() {return mount;}
void setMount(int mount) { this->mount = mount;}
};
class IDeduction
{
public:
virtual bool exec(Card *card, Trade *trade) = 0;
};
class SteadyDeduction:public IDeduction
{
public:
SteadyDeduction(){}
~SteadyDeduction(){}
bool exec(Card *card, Trade *trade)
{
int halfMoney = (int)(trade->getMount() / 2.0);
card->setSteadyMoney(card->getSteadyMoney() - halfMoney);
card->setFreeMoney(card->getFreeMoney() - halfMoney);
return true;
}
};
class FreeDeduction:public IDeduction {
public :
FreeDeduction(){}
~FreeDeduction(){}
bool exec(Card *card, Trade *trade)
{
card->setFreeMoney(card->getFreeMoney() - trade->getMount());
return true;
}
};
class DeductionContext {
private:
IDeduction *deduction;
public :
DeductionContext(IDeduction *deduction) {
this->deduction = deduction;
}
bool exec(Card *card, Trade *trade) {
return this->deduction->exec(card, trade);
}
};
class StrategyManage
{
private:
string value;
public:
StrategyManage(string value) {
this->value = value;
}
string getValue() { return value;}
};
class StrategyFactory {
public :
IDeduction *deduction;
IDeduction* getDeduction(string strategy) {
try {
if(strategy=="SteadyDeduction")
deduction = new SteadyDeduction();
else if(strategy=="FreeDeduction")
deduction = new FreeDeduction();
} catch (exception e) {
}
return deduction;
}
};
//扣款模块封装
class DeductionFacade {
public:
Card *deduct(Card *card, Trade *trade) {
StrategyManage *reg = new StrategyManage("FreeDeduction"); //获得消费策略
StrategyFactory *factory = new StrategyFactory();
IDeduction *deduction = factory->getDeduction(reg->getValue()); //初始化一个消费策略 对象
DeductionContext *context = new DeductionContext(deduction); //执行封装
context->exec(card, trade); //执行扣款
return card;
}
private:
// StrategyManage getDeducationType(Trade trade) {
// if (trade.getTradeNo().contains("abc")) {
// return StrategyManage.FreeDeducation;
// }else {
// return StrategyManage.SteadyDeduction;
// }
//}
};
class Client {
public :
Card *initCard() {
Card *card = new Card();
card->setNo("10000");
card->setFreeMoney(1000);
card->setSteadyMoney(1000);
return card;
}
Trade *initTrade() {
Trade *trade = new Trade();
trade->setMount(0);
trade->setTradeNo("");
return trade;
}
Trade *CreateTrade(int charge) {
Trade *trade = new Trade();
trade->setMount(charge);
trade->setTradeNo("asasdasa");
return trade;
}
void showCard(Card *card)
{
cout<< card->getFreeMoney() << "\t"<getSteadyMoney() << endl;
}
};
int main()
{
Client *cli =new Client();
DeductionFacade *facade =new DeductionFacade();
Card *card = cli->initCard();
Trade *trade = cli->initTrade();
trade = cli->CreateTrade(100);
cli->showCard(card);
card = facade->deduct(card,trade);
cli->showCard(card);
return 0;
}
</code></pre>
在该场景中用到如下几个设计模式:
####策略(strategy)模式:负载对扣款策略进行封装,保证了两个策略可以自由的切换。
####工厂(factory)模式:修正策略模式必须对外暴露具体策略的问题,由工厂模式直接产生一个具体策略对象,其他模块则不需要依赖具体策略。
####门面(facade)模式:负责对复杂的扣款系统进行封转,封转的结果就是避免高层模块深入子系统内部,同时提供系统高内聚、低耦合的特性。