002 --- 第2章 策略模式
简述:
策略模式定义了算法家族,分别封装起来,让他们之间可以互相替换,此设计模式让算法的变化,不会影响到使用算法的客户。
策略模式包括:抽象策略类、具体策略类、上下文类。
抽象策略类:定义所有支持的算法的公共接口。
具体策略类:继承自抽象策略类,封装了具体的算法活行为。
上下文类:用一个具体策略类的指针对象来配置一个对抽象策略类的指针。
策略模式可以结合简单工厂模式一起使用,设计模式的组合配搭,可根据具体需求自如运用。
应用场景:策略模式就是用来封装算法的,但在实践中,我们发现可以用它来封装几乎任何类型的规则,只要在分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑使用策略模式来处理这种变化的可能性
注:开发环境调整为VS2017,操作系统win11
策略模式代码:
1 #include <iostream> 2 using namespace std; 3 4 // 策略模式 5 // 抽象策略类:定义所有支持的算法的公共接口 6 class CStrategy 7 { 8 public: 9 virtual void AlgorithmInterface() = 0; 10 }; 11 12 // 具体策略类A:封装了具体的算法或行为 13 class CConcreteStrategyA : public CStrategy 14 { 15 public: 16 virtual void AlgorithmInterface() 17 { 18 cout << "算法A实现" << endl; 19 } 20 }; 21 22 // 具体策略类B:封装了具体的算法或行为 23 class CConcreteStrategyB : public CStrategy 24 { 25 public: 26 virtual void AlgorithmInterface() 27 { 28 cout << "算法B实现" << endl; 29 } 30 }; 31 32 // 具体策略类C:封装了具体的算法或行为 33 class CConcreteStrategyC : public CStrategy 34 { 35 public: 36 virtual void AlgorithmInterface() 37 { 38 cout << "算法C实现" << endl; 39 } 40 }; 41 42 // 上下文类:用一个具体策略类的指针对象来配置一个对抽象策略类的指针 43 class CContext 44 { 45 private: 46 CStrategy* m_pStrategy; 47 48 public: 49 CContext(CStrategy* pStrategy) 50 { 51 m_pStrategy = pStrategy; 52 } 53 54 ~CContext() 55 { 56 if (m_pStrategy) 57 { 58 delete m_pStrategy; 59 m_pStrategy = NULL; 60 } 61 } 62 63 void ContextInterface() 64 { 65 m_pStrategy->AlgorithmInterface(); 66 } 67 }; 68 69 int main() 70 { 71 CContext Context1(new CConcreteStrategyA()); 72 Context1.ContextInterface(); 73 74 CContext Context2(new CConcreteStrategyB()); 75 Context2.ContextInterface(); 76 77 CContext Context3(new CConcreteStrategyC()); 78 Context3.ContextInterface(); 79 80 system("pause"); 81 return 0; 82 }
输出结果:
例:商场打折促销手段分类(策略模式与工厂模式结合使用)
代码如下:
1 #include <iostream> 2 using namespace std; 3 4 // 收费基类(抽象策略类) 5 class CCashSuper 6 { 7 public: 8 virtual double AcceptCash(double dMoney) 9 { 10 return dMoney; 11 } 12 }; 13 14 // 正常收费子类(具体策略类) 15 class CCashNormal : public CCashSuper 16 { 17 public: 18 virtual double AcceptCash(double dMoney) 19 { 20 return dMoney; 21 } 22 }; 23 24 // 打折收费子类(具体策略类) 25 class CCashRebate : public CCashSuper 26 { 27 private: 28 double m_dMoneyRebate; 29 30 public: 31 CCashRebate(double dMoneyRebate) 32 { 33 m_dMoneyRebate = dMoneyRebate; 34 } 35 36 virtual double AcceptCash(double dMoney) 37 { 38 return dMoney * m_dMoneyRebate; 39 } 40 }; 41 42 // 返利收费子类(具体策略类) 43 class CCashReturn : public CCashSuper 44 { 45 private: 46 double m_dMoneyCondition; 47 double m_dMoneyReturn; 48 49 public: 50 CCashReturn(double dMoneyCondition, double dMoneyReturn) 51 { 52 m_dMoneyCondition = dMoneyCondition; 53 m_dMoneyReturn = dMoneyReturn; 54 } 55 56 virtual double AcceptCash(double dMoney) 57 { 58 double dResult = dMoney; 59 if (dMoney >= m_dMoneyCondition) 60 dResult = dMoney - ((int)dMoney / (int)m_dMoneyCondition) * m_dMoneyReturn; 61 62 return dResult; 63 } 64 }; 65 66 // 上下文类与简单工厂模式结合 67 enum TYPE { NORMAL, REBATE, RETURN }; 68 class CCashContext 69 { 70 private: 71 CCashSuper* m_pCashSuper; 72 73 public: 74 CCashContext(int nType) : m_pCashSuper(NULL) 75 { 76 switch (nType) 77 { 78 case NORMAL: 79 { 80 CCashNormal* pCashNormal = new CCashNormal(); 81 m_pCashSuper = pCashNormal; 82 } 83 break; 84 case REBATE: 85 { 86 CCashRebate* pCashRebate = new CCashRebate(0.8); 87 m_pCashSuper = pCashRebate; 88 } 89 break; 90 case RETURN: 91 { 92 CCashReturn* pCashReturn = new CCashReturn(300, 100); 93 m_pCashSuper = pCashReturn; 94 } 95 break; 96 } 97 } 98 99 ~CCashContext() 100 { 101 if (m_pCashSuper) 102 { 103 delete m_pCashSuper; 104 m_pCashSuper = NULL; 105 } 106 } 107 108 double GetResult(double dMoney) 109 { 110 return m_pCashSuper->AcceptCash(dMoney); 111 } 112 }; 113 114 115 int main() 116 { 117 double dTotal = 0; 118 int nType = REBATE; 119 CCashContext CashContext(nType); 120 121 double dTotalPrices = 0; 122 double dPrice = 200; 123 int nCount = 3; 124 dTotalPrices = CashContext.GetResult(dPrice * nCount); 125 dTotal = dTotal + dTotalPrices; 126 cout << "单价:[" << dPrice << "] " 127 << "数量:[" << nCount << "] " 128 << "打折:[" << nType << "] " 129 << "合计:[" << dTotal << "] " << endl; 130 131 system("pause"); 132 return 0; 133 }
输出结果: