在我还不太懂设计模式的时候,代码写的非常混乱,往往都是拍拍脑袋就写代码,写到哪里算哪里,不行就往死里改,效率低下。当然学习设计模式的过程也十分有趣,可是说是建立自己设计思维的基石。在学习的时候,不但要充分思考这样设计的方案好在哪里差在哪里,更关键的是,要动手去写,否则只是理解表层的东西,很难做到融会贯通。
学习设计模式的过程:
1. 创建型模式
2. 结构型模式
3. 行为模式
现在,我们就先从创建型模式开始:所谓创建型模式,就是指构建类对象。帮助系统隔离开“如何创建?”、“如何组合?”、“表示的对象?”。
我们既然使用了C++,就需要充分使用面向对象的优越性,那就是通过封装、继承、多态来把程序的耦合度降低,提高程序的灵活性和复用性。
废话不多说了,直接开始关于简单工厂的实现。
简单工厂模式UML图:
1. 只有1个产品对象的简单工厂模式
2. 带有1个抽象产品对象的简单工厂模式
因为是简单工厂模式,所以设计上只有一个工厂,或者说只有一种类型的工厂,没办法,都说是“简单”了,几个工厂就不叫简单了。
简单工厂的目的仅仅聚焦于:
抽象出产品,然后根据产品需求创建不同产品对象
1 /************************************************************************/ 2 /* 简单实现 */ 3 /************************************************************************/ 4 int main(int argc, char* argv[]) 5 { 6 // 创建工厂 7 CFactory cFactory; 8 CProduct *pcPro; 9 pcPro = cFactory.CreateProduct(PRODUCT_TYPE_3); 10 pcPro->ProductBehavior(); 11 pcPro = cFactory.CreateProduct(PRODUCT_TYPE_1); 12 pcPro->ProductBehavior(); 13 pcPro = cFactory.CreateProduct(PRODUCT_TYPE_2); 14 pcPro->ProductBehavior(); 15 16 printf("Hello World! "); 17 return 0; 18 }
1 /************************************************************************/ 2 /* 简单工厂模式模板 */ 3 /************************************************************************/ 4 5 enum emProductType 6 { 7 PRODUCT_TYPE_1 = 0, 8 PRODUCT_TYPE_2, 9 PRODUCT_TYPE_3 10 }; 11 12 class CFactory 13 { 14 public: 15 CFactory(){}; 16 // 抽象创建产品 17 CProduct* CreateProduct(int wParam) 18 { 19 switch(wParam) 20 { 21 case PRODUCT_TYPE_1: 22 return new CProductA(); 23 case PRODUCT_TYPE_2: 24 return new CProductB(); 25 case PRODUCT_TYPE_3: 26 return new CProductC(); 27 default: 28 break;; 29 } 30 return 0; 31 }; 32 protected: 33 private: 34 };
1 /************** 2 * 抽象产品类 * 3 **************/ 4 class CProduct 5 { 6 public: 7 virtual BOOL ProductBehavior(void){return TRUE;}; 8 int m_wParam; 9 protected: 10 private: 11 }; 12 13 /************** 14 * 产品-A * 15 **************/ 16 class CProductA : public CProduct 17 { 18 public: 19 CProductA() 20 { 21 m_wParam = 1; 22 m_wParamA = 1; 23 } 24 BOOL ProductBehavior(void) 25 { 26 printf("m_wParam:%d,m_wParamA:%d ", m_wParam,m_wParamA); 27 return TRUE; 28 }; 29 protected: 30 private: 31 int m_wParamA; 32 }; 33 34 /************** 35 * 产品-B * 36 **************/ 37 class CProductB : public CProduct 38 { 39 public: 40 CProductB() 41 { 42 m_wParam = 2; 43 m_wParamB = 2; 44 } 45 BOOL ProductBehavior(void) 46 { 47 printf("m_wParam:%d,m_wParamB:%d ", m_wParam,m_wParamB); 48 return TRUE; 49 }; 50 protected: 51 private: 52 int m_wParamB; 53 }; 54 55 /************** 56 * 产品-C * 57 **************/ 58 class CProductC : public CProduct 59 { 60 public: 61 CProductC() 62 { 63 m_wParam = 3; 64 m_wParamC = 4; 65 m_wMathC = 5; 66 } 67 BOOL ProductBehavior(void) 68 { 69 printf("m_wParam:%d,m_wParamC:%d,m_wMathC:%d ", m_wParam,m_wParamC,m_wMathC); 70 return TRUE; 71 }; 72 protected: 73 private: 74 int m_wParamC; 75 int m_wMathC; 76 };
最后的实现结果:
这里需要说明下main函数里,关于使用CProduct *:父类指针指向子类对象
1.如果一个父类指针指向一个子类对象,那么经由该指针只能访问基础类定义的函数;
2.如果一个子类指针指向一个父类对象,这样尽量避免;
3.如果定义了相同名称的成员函数,那么通过对象指针调用成员函数时,调用哪个函数,取决于指针类型来决定,而不是实际对象决定;
如果父类接口是虚函数,那么就不同了,父类指针指向了子类对象,那么实现的就是子类的方法;如果父类指针指向父类对象,那么实现的仍是父类方法;