先使用简单工厂模式为一个商场的收银员写一个收银的简单代码:
#include<iostream>
using namespace std;
class cash
{
public:
double money = 0;
virtual int getmoney()
{
int result = 0;
return result;
}
};
class normalcash :public cash
{
int getmoney()
{
int result = money;
return result;
}
};
class ratecash :public cash
{
public:
int getmoney()
{
double rate = 1;
cout << "输入折扣率: " << endl;
cin >> rate;
double result = rate*money;
return result;
}
};
class fanlicash :public cash
{
int getmoney()
{
int result = money>100?money-10:money;
return result;
}
};
class cashfactory
{
public:
static cash* createstrategy(int strategy)
{
cash* cs = nullptr;
switch (strategy)
{
case 0:cs = new normalcash(); break;//父类指针可以指向子类
case 1:cs = new ratecash(); break;
case 2:cs = new fanlicash(); break;
}
return cs;
}
};
void main()
{
cout << "选择收费模式:" << endl<< "0:正常收费 " << endl << "1:打折收费 " << endl << "2:返利收费" << endl;
cash* cs;
int s1 = 0;
cin >> s1;
cs = cashfactory::createstrategy(s1);
int sum = 0;
cout << "总金额: " << endl;
cin >> sum;
cs->money = sum;
try { cout <<"最后消费"<<endl<<cs->getmoney(); }
catch (char r) { cout << "是打折哦" << endl; }
}
由于工厂本身包含了所有的收费方式,然而商场的促销活动五花八门,经常变化,可能经常性更改打折额度和返利额度,每次维护或者扩展收费方法都要改动这个工厂,以致代码需要重新编译部署,所以我们引入一种新的设计模式:策略模式,策略模式定义了算法家族,分别封装起来,让它们之间可以相互替换,此模式让算法的变化,不会影响到使用算法的客服。即封装变化点:将所有可能变化的代码封装起来,与不变的代码分离开来。
UML类图:
class cashcontext
{
public:
cash* cs = nullptr;
cashcontext(int strategy)
{
switch (strategy)
{
case 0:cs = new normalcash(); break;//父类指针可以指向子类
case 1:cs = new ratecash(); break;
case 2:cs = new fanlicash(); break;
}
}
int getmoney()
{
return cs->getmoney();
}
};
void main()
{
cout << "选择收费模式:" << endl<< "0:正常收费 " << endl << "1:打折收费 " << endl << "2:返利收费" << endl;
int s1 = 0;
cin >> s1;
cashcontext* cc = new cashcontext(s1);
int sum = 0;
cout << "总金额: " << endl;
cin >> sum;
cc->cs->money= sum;
try { cout <<"最后消费"<<endl<<cc->getmoney(); }
catch (char r) { cout << "是打折哦" << endl; }
}
这里是将策略模式与工厂模式结合,即将模式选择的部分交给了cashcontext
cashcontext接收一个具体的策略对象(或者具体策略对象对应的标记),然后根据具体的策略对象,调用其算法的方法,在没有和策略模式结合时,具体算法由指向策略对象的父类指针调用,若增加策略时工厂类要增加case,还要实现要增加的具体的策略,这两者都是变化的,而策略模式的核心在于封装变化点,即将这二者的通过cashcontext进行封装,原本客户端需要看到工厂类与策略的父类这两个类,现在只需要看到cashcontext这一个类