其实这个三个C++的设计模式已经学习很长时间了,今晚才想起来要写这三个设计模式,为什么要用C++中的设计模式呢?for example,你已经会开车了,正着开,倒着开,转弯,这些都是开车基本的,但是你并没有很高的车技,并不会炫酷。漂移,就好像C++中的设计模式一样,在你学好C++的基础上,娴熟的应用出的新技能,能让你的车开的更好。
为什么要用简单工厂模式,记得上一次,我虽然敲完了代码,但是当别人突然问一句,你为什么要用简单工厂模式,我突然就愣住了,代码很简单,一看就懂了。重要的还是思想。专门定义一个类来负责创建其他类的实例,这个专门建立对象的类,向外暴漏创建对象的接口,供外部调用。工厂模式有一种非常形象的描述,建立对象的类就如一个工厂,而需要被建立的对象就是一个产品;在工厂中加工产品,使用产品的人,不用在乎产品是如何生产出来的。从软件开发的角度来说,这样就有效的降低了模块之间的耦合。
这次我就用老婆和菜来说明简单工厂模式,我有一个老婆,她就是工厂Factory,老婆Factory会做的菜就是ProductA(西红柿炒鸡蛋),ProductB(炒饼丝),ProductC(香嘴鱼),我就是老公。我今天对老婆说,我要吃ProductB(炒饼丝),然后老婆就说好,而我并不需要老婆是怎么做,或者是不是我老婆做的(她也可以叫外卖),最后我只要看见ProductB(炒饼丝)就好了。
下面的这个UML我只是简单的画了一下,并没有添加数据成员,但是你们在代码中看出来了,我也会详细的说的
第一个简单工厂模式就是这个样子了,在客户端只要创建你想想要吃的菜,那么只要个老婆Factory一说,就让她去做吧,然后呢,你就可以坐等吃饭。上代码:
/* 简单工厂模式 */ #include <iostream> using namespace std; class Product{ public: virtual void operation()=0; ~Product(){ } }; class ProductA:public Product{ public: void operation(){ cout<<"西红柿炒鸡蛋"<<endl; } ~ProductA(){ } }; class ProductB:public Product{ public: void operation(){ cout<<"炒饼丝"<<endl; } ~ProductB(){ } }; class ProductC:public Product{ public: void operation(){ cout<<"香嘴鱼"<<endl; } ~ProductC(){ } }; class Factory{ protected: Product *p; public: Factory(Product *t){ p=t; } void operation(){ p->operation(); } ~Factory(){ } }; int main(int argc, char** argv) { //创建一个基类指针指向一个西红柿炒鸡蛋的对象 Product *pA = new ProductA(); //创建一个基类指针指向一个炒饼丝的对象 Product *pB = new ProductB(); //创建工厂的指针 Factory *pFa1 = new Factory(pA); Factory *pFa2 = new Factory(pB); pFa1->operation(); pFa2->operation(); delete pA; delete pB; delete pFa1; delete pFa2; return 0; }
上面的代码注释很清晰了,创建一个基类指针指向一个西红柿炒鸡蛋的对象,创建一个基类指针指向一个炒饼丝的对象,创建工厂的指针,然后调用一下就可以了。
演示结果:
其实这个简单工厂模式肯定不好啊,如果你想你要吃更多的菜的话,那还不把自己的老婆累死,为了减轻老婆的压力,我们可以在取老婆,这个时候抽象出来一个大老婆Factory,管其他的老婆FactoryA,FactoryB。让一个老婆做一个菜,FactoryA老婆就做ProductA西红柿炒鸡蛋,FactoryB就做ProductB炒饼丝,这没啥,任性,钱多。。。
说正经的,扩展工厂使其不同的工厂负责不同的功能。来点专业的说法,工厂方法模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。
代码实现如下:
/* 这是之前的简单工厂模式演化而来 工厂模式 */ #include <iostream> using namespace std; //做啥菜 class Product{ public: virtual void operation()=0; ~Product(){ } }; class ProductA:public Product{ public: void operation(){ cout<<"西红柿炒鸡蛋"<<endl; } ~ProductA(){ } }; class ProductB:public Product{ public: void operation(){ cout<<"炒饼丝"<<endl; } ~ProductB(){ } }; class ProductC:public Product{ public: void operation(){ cout<<"香嘴鱼"<<endl; } ~ProductC(){ } }; class ProductD:public Product{ public: void operation(){ cout<<"6元麻辣烫"<<endl; } ~ProductD(){ } }; class ProductE:public Product{ public: void operation(){ cout<<"岐山臊子面"<<endl; } ~ProductE(){ } }; class ProductF:public Product{ public: void operation(){ cout<<"肉夹馍"<<endl; } ~ProductF(){ } }; //工厂老婆 class Factory{ protected: Product *p; public: virtual void dofun()=0; }; class FactoryA:public Factory{ public: FactoryA(Product *t){ p=t; } void dofun(){ p->operation(); } }; class FactoryB:public Factory{ public: FactoryB(Product *t){ p=t; } void dofun(){ p->operation(); } }; int main(int argc, char** argv) { //创建一个基类指针指向一个西红柿炒鸡蛋的对象 Product *pA = new ProductA(); //创建一个基类指针指向一个炒饼丝的对象 Product *pB = new ProductB(); //创建一个基类指针指向一个岐山臊子面的对象 Product *pE = new ProductE(); //创建一个基类指针指向一个肉夹馍的对象 Product *pF = new ProductF(); //创建工厂的指针 Factory *pFa1 = new FactoryA(pA); Factory *pFa2 = new FactoryA(pB); Factory *pFa3 = new FactoryB(pE); Factory *pFa4 = new FactoryB(pF); cout<<"输出工厂FactoryA老婆做的饭菜"<<endl; pFa1->dofun(); pFa2->dofun(); cout<<"输出工厂FactoryB老婆做的饭菜"<<endl; pFa3->dofun(); pFa4->dofun(); delete pA; delete pB; delete pE; delete pF; delete pFa1; delete pFa2; delete pFa3; delete pFa4; return 0; }
很清楚了,代码有注释,想吃啥,就弄啥,结果演示:
其实这个样子还不好,还是前面说到的问题,随着菜品类的增加,老婆的增加,这也就越来越复杂了,如果增加一个菜,你就来一个老婆,这就违背了开闭原则(在之前的博客提到过),这不好啊。因此我们再次抽象菜的种类。比如说,我把陕西的菜归为一个类ProductA,把四川的菜归为一个ProductB,山东的菜归为一个ProductC,说到底,为了 所有东西,为了简单都是抽象在抽象。也不多唧唧歪歪了,上图:
代码演示:
/* 这是之前的工厂模式演化而来 抽象工厂模式 */ #include <iostream> using namespace std; class Product{ public: virtual void operation()=0; ~Product(){ } }; class ProductSiChuan:public Product{ public: virtual void operation()=0; }; class ProductA:public ProductSiChuan{ public: void operation(){ cout<<"四川西红柿炒鸡蛋"<<endl; } ~ProductA(){ } }; class ProductB:public ProductSiChuan{ public: void operation(){ cout<<"四川炒饼丝"<<endl; } ~ProductB(){ } }; class ProductC:public ProductSiChuan{ public: void operation(){ cout<<"四川香嘴鱼"<<endl; } ~ProductC(){ } }; class ProductShaanxi:public Product{ public: virtual void operation()=0; }; class ProductD:public ProductShaanxi{ public: void operation(){ cout<<"陕西6元麻辣烫"<<endl; } ~ProductD(){ } }; class ProductE:public ProductShaanxi{ public: void operation(){ cout<<"陕西岐山臊子面"<<endl; } ~ProductE(){ } }; class ProductF:public ProductShaanxi{ public: void operation(){ cout<<"陕西biangbiang面"<<endl; } ~ProductF(){ } }; //山东的好吃滴 class ProductShanDong:public Product{ public: virtual void operation()=0; }; class ProductG:public ProductShanDong{ public: void operation(){ cout<<"山东煎饼"<<endl; } ~ProductG(){ } }; class ProductH:public ProductShanDong{ public: void operation(){ cout<<"山东烤鸭"<<endl; } ~ProductH(){ } }; class ProductI:public ProductShanDong{ public: void operation(){ cout<<"山东大闸蟹"<<endl; } ~ProductI(){ } }; // 工厂老婆 class Factory{ protected: Product *p; public: virtual void dofun()=0; }; class FactoryA:public Factory{ public: FactoryA(Product *t){ p=t; } void dofun(){ p->operation(); } }; class FactoryB:public Factory{ public: FactoryB(Product *t){ p=t; } void dofun(){ p->operation(); } }; class FactoryC:public Factory{ public: FactoryC(Product *t){ p=t; } void dofun(){ p->operation(); } }; int main(int argc, char** argv) { //创建一个基类指针指向四川西红柿炒鸡蛋一个的对象 Product *pA = new ProductA(); //创建一个基类指针指向一个四川炒饼丝的对象 Product *pB = new ProductB(); //创建一个基类指针指向一个陕西岐山臊子面的对象 Product *pC = new ProductD(); //创建一个基类指针指向一个陕西麻辣烫的对象 Product *pD = new ProductE(); //创建一个基类指针指向一个山东煎饼的对象 Product *pE = new ProductG(); //创建工厂的指针 Factory *pFa1 = new FactoryA(pA); Factory *pFa2 = new FactoryA(pB); Factory *pFa3 = new FactoryB(pC); Factory *pFa4 = new FactoryB(pD); Factory *pFa5 = new FactoryC(pE); cout<<"输出工厂FactoryA老婆做的饭菜"<<endl; pFa1->dofun(); pFa2->dofun(); cout<<"输出工厂FactoryB老婆做的饭菜"<<endl; pFa3->dofun(); pFa4->dofun(); cout<<"输出工厂FactoryC老婆做的饭菜"<<endl; pFa5->dofun(); delete pA; delete pB; delete pC; delete pD; delete pE; delete pFa1; delete pFa2; delete pFa3; delete pFa4; delete pFa5; return 0; }
结果演示:
这个时候突然想起来一点还没有说呢,就是在UML图中,Factory中就有Product的数据成员,这样就实现了类与类之间的通信。
本人菜菜鸟一枚,如果有啥错误,欢迎指出,感激不尽,
原文地址:http://blog.csdn.net/lotluck/article/details/45624891