面向对象的编程,并不是类越多越好,类的划分是为了封装,但分类的基础是抽象,具有相同属性和功能的对象的抽象集合才是类。
商场收银软件的简单工厂实现

#include<iostream> using namespace std; class CashSuper { public: virtual double acceptCash(double money) = 0; }; class CashNormal : public CashSuper { public: double acceptCash(double money) { return money; } }; class CashRebate : public CashSuper { private: double moneyRebate; public: CashRebate(double moneyRebate_t) : moneyRebate(moneyRebate_t) {} double acceptCash(double money) { return money * moneyRebate; } }; class CashReturn : public CashSuper { private: double moneyCondition; double moneyReturn; public: CashReturn(double moneyCondition_t, double moneyReturn_t) : moneyCondition(moneyCondition_t), moneyReturn(moneyReturn_t) {} double acceptCash(double money) { double result = money; if (money >= moneyCondition) result = money = (money - moneyCondition)*moneyReturn; return result; } }; class CashFactory { public: static CashSuper* createCashAccept(int type) { CashSuper *cs = nullptr; switch (type) { case 1: cs = new CashNormal; break; case 2: cs = new CashRebate(0.8); break; case 3: cs = new CashReturn(300, 100); break; } return cs; } }; int main() { double price, num; cout << "请输入单价和数量:" << endl; cin >> price >> num; double total = price * num; cout << "1.正常收费" << endl; cout<<"2.打8折"<<endl; cout<<"3.满300返100"<<endl; cout << "请输入促销条件前的数字序号: " << endl; int type; cin >> type; CashSuper *cs = CashFactory::createCashAccept(type); double result = cs->acceptCash(total); cout << result << endl; system("pause"); return 0; }
由于工厂本身包括了所有的收费方式,商场是可能经常性的更改打折额度和返利额度,每次维护或者扩展收费方式都要改动这个工厂,以致代码需要重新编译部署,所以用它不是最好的办法。
策略模式(Strategy): 它定义了算法家族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。

商场收银软件的策略模式加简单工厂实现

#include<iostream> using namespace std; /*定义所有支持的算法的公共接口*/ class CashSuper { public: virtual double acceptCash(double money) = 0; }; /*封装了具体的算法或行为*/ class CashNormal : public CashSuper { public: /*具体算法的实现*/ double acceptCash(double money) { return money; } }; class CashRebate : public CashSuper { private: double moneyRebate; public: CashRebate(double moneyRebate_t) : moneyRebate(moneyRebate_t) {} double acceptCash(double money) { return money * moneyRebate; } }; class CashReturn : public CashSuper { private: double moneyCondition; double moneyReturn; public: CashReturn(double moneyCondition_t, double moneyReturn_t) : moneyCondition(moneyCondition_t), moneyReturn(moneyReturn_t) {} double acceptCash(double money) { double result = money; if (money >= moneyCondition) result = money = (money - moneyCondition)*moneyReturn; return result; } }; /*用一个ConcreteStrategy来配置,维护一个对Strategy对象的引用*/ class CashContext { private: CashSuper *cs = nullptr; int type; public: /*集合了简单工厂模式,初始化时,传入具体的策略对象*/ CashContext(int t): type(t) { switch(type) { case 1: cs = new CashNormal; break; case 2: cs = new CashRebate(0.8); break; case 3: cs = new CashReturn(300, 100); break; } } /*上下文接口,根据具体的策略对象,调用其算法的方法*/ double GetResult(double money) { return cs->acceptCash(money); } }; int main() { double price, num; cout << "请输入单价和数量:" << endl; cin >> price >> num; double total = price * num; cout << "1.正常收费" << endl; cout<<"2.打8折"<<endl; cout<<"3.满300返100"<<endl; cout << "请输入促销条件前的数字序号: " << endl; int type; cin >> type; CashContext *csuper = new CashContext(type); double result = csuper->GetResult(total); cout << result << endl; system("pause"); return 0; }
简单工厂模式我们需要让客户端认识两个类,CashSuper和CashFactory,而策略模式与简单工厂模式结合的用法,客户端只需要认识一个类CashContext就可以了,耦合更加降低。
策略模式解析
策略模式是一种定义一系列算法的方法,从概念上来看,所有这些算法完成的都是相同的工作,只是实现不同,他可以以相同的方式调用所有的算法,减少了各种算法类与使用算法类之间的耦合。
策略模式的Strategy类层次为Context定义了一系列的可供重用的算法或行为。继承有助于析取出这些算法的公共功能。
另一个策略模式的优点是简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单独测试。
当不同的行为堆砌在一个类中时,就很难避免使用条件语句来选择合适的行为。将这些行为封装在一个个独立的Strategy类中,可以在使用这些行为的类中消除条件语句。
策略模式就是用来封装算法的,但在实践中,我们发现可以用它来封装几乎任何类型的规则,只要在分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性。