先使用简单工厂模式为一个商场的收银员写一个收银的简单代码:
#includeusing 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 <<"最后消费"< 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 <<"最后消费"<getmoney(); }
catch (char r) { cout << "是打折哦" << endl; }
}
这里是将策略模式与工厂模式结合,即将模式选择的部分交给了cashcontext
cashcontext接收一个具体的策略对象(或者具体策略对象对应的标记),然后根据具体的策略对象,调用其算法的方法,在没有和策略模式结合时,具体算法由指向策略对象的父类指针调用,若增加策略时工厂类要增加case,还要实现要增加的具体的策略,这两者都是变化的,而策略模式的核心在于封装变化点,即将这二者的通过cashcontext进行封装,原本客户端需要看到工厂类与策略的父类这两个类,现在只需要看到cashcontext这一个类



