一、简单工厂模式:
简单工厂模式是工厂模式中最简单的一种,他可以用比较简单的方式隐藏创建对象的细节,一般只需要告诉工厂类所需要的类型,工厂类就会返回需要的产品类,但客户端看到的只是产品的抽象对象,无需关心到底是返回了哪个子类。客户端唯一需要知道的具体子类就是工厂子类。除了这点,基本是达到了依赖倒转原则的要求。
假如,我们不用工厂类,只用CreateOperate和它的子类,那客户端每次使用不同的子类的时候都需要知道到底是用哪一个子类,当类比较少的时候还没什么问题,但是当类比较多的时候,管理起来就非常的麻烦了,就必须要做大量的替换,一个不小心就会发生错误。而使用了工厂类之后,就不会有这样的问题,不管里面多少个类,我只需要知道类型号即可。不过,这里还有一个疑问,那就是如果我每次用工厂类创建的类型都不相同,这样修改起来的时候还是会出现问题,还是需要大量的替换。所以简单工厂模式一般应该于程序中大部分地方都只使用其中一种“产品”,工厂类也不用频繁创建产品类的情况。这样修改的时候只需要修改有限的几个地方即可。
看了许多工厂模式的例子,觉得加减乘除运算工厂模式最能直观易懂的讲解工厂模式,当需要加法类的时候,调用工厂类的CreateOperate(),要指定生产相应的“产品”,见类图:
#include <iostream> #include <string> using namespace std; class Operation { public: double numberA, numberB; virtual double getResult() { return 0; } }; class addOperation :public Operation { double getResult() { return numberA + numberB; } }; class subOperation :public Operation { double getResult() { return numberA - numberB; } }; class mulOperation :public Operation { double getResult() { return numberA*numberB; } }; class divOperation :public Operation { double getResult() { return numberA / numberB; } }; class operFactory { public: static Operation *createOperation(char c) { switch (c) { case '+': return new addOperation; break; case '-': return new subOperation; break; case '*': return new mulOperation; break; case '/': return new divOperation; break; } } }; int main() { Operation *oper = operFactory::createOperation('+'); //Operation *oper = operFactory::createOperation('-'); //Operation *oper = operFactory::createOperation('*'); //Operation *oper = operFactory::createOperation('/'); oper->numberA = 9; oper->numberB = 99; cout << oper->getResult() << endl; return 0; }
调用工厂,需要createOperator("/"),就能返回除法运算符。
优点:客户端不需要修改代码。
缺点: 当需要增加新的运算类的时候,不仅需新加运算类,还要修改工厂类,违反了开闭原则。
二、工厂方法模式:
UML类图如下:
#include <iostream> #include <string> using namespace std; class Operation { public: double numberA,numberB; virtual double getResult() { return 0; } }; class addOperation:public Operation { double getResult() { return numberA+numberB; } }; class subOperation:public Operation { double getResult() { return numberA-numberB; } }; class mulOperation:public Operation { double getResult() { return numberA*numberB; } }; class divOperation:public Operation { double getResult() { return numberA/numberB; } }; class IFactory { public: virtual Operation *createOperation()=0; }; class AddFactory:public IFactory { public: static Operation *createOperation() { return new addOperation(); } }; class SubFactory:public IFactory { public: static Operation *createOperation() { return new subOperation(); } }; class MulFactory:public IFactory { public: static Operation *createOperation() { return new mulOperation(); } }; class DivFactory:public IFactory { public: static Operation *createOperation() { return new divOperation(); } }; int main() { Operation *oper=MulFactory::createOperation(); oper->numberA=9; oper->numberB=99; cout<<oper->getResult()<<endl; return 0; }
这个和简单工厂有区别,简单工厂模式只有一个工厂,工厂方法模式对每一个产品都有相应的工厂
好处:增加一个运算类(例如N次方类),只需要增加运算类和相对应的工厂,两个类,不需要修改工厂类。
缺点:增加运算类,会修改客户端代码,工厂方法只是把简单工厂的内部逻辑判断移到了客户端进行。
三、抽象工厂模式:
以股票行情沪深板块行情数据访问为例,行情源访问程序设计,不同的行情访问方式可能不一样,为了抽象对对不同行情的访问,可以将行情源隐藏起来,提供统一的访问方式,用多态进行实现。
#include <iostream> #include <string> using namespace std; class Icode { public: virtual void Getcode()=0; virtual void Setcode()=0; }; class ShenAcode:public Icode { public: void Getcode() { cout<<"在ShenA中返回code"<<endl; } void Setcode() { cout<<"在ShenA中设置code"<<endl; } }; class ShangAcode:public Icode { public: void Getcode() { cout<<"在ShangA中返回code"<<endl; } void Setcode() { cout<<"在ShangA中设置code"<<endl; } }; class Iindex { public: virtual void Getindex()=0; virtual void Setindex()=0; }; class ShenAindex:public Iindex { public: void Getindex() { cout<<"在ShenA中返回index"<<endl; } void Setindex() { cout<<"在ShenA中设置index"<<endl; } }; class ShangAindex:public Iindex { public: void Getindex() { cout<<"在ShangA中返回index"<<endl; } void Setindex() { cout<<"在ShangA中设置index"<<endl; } }; class IFactory { public: virtual Icode *CreateCode()=0; virtual Iindex *CreateIndex()=0; }; class ShenAFactory:public IFactory { public: Icode *CreateCode() { return new ShenAcode(); } Iindex *CreateIndex() { return new ShenAindex(); } }; class ShangAFactory:public IFactory { public: Icode *CreateCode() { return new ShangAcode(); } Iindex *CreateIndex() { return new ShangAindex(); } }; /*************************************************************/ class DataShangA { private: static string stock; //string stock="ShangA"; public: static Icode *CreateCode() { if(stock=="ShangA") { return new ShangAcode(); } else if(stock=="ShenA") { return new ShenAcode(); } } static Iindex *CreateIndex() { if(stock=="ShangA") { return new ShangAindex(); } else if(stock=="ShenA") { return new ShenAindex(); } } }; string DataShangA::stock="ShenA"; /*************************************************************/ int main() { //IFactory *factory=new ShenAFactory(); IFactory *factory; Icode *code; Iindex *index; factory=new ShangAFactory(); code=factory->CreateCode(); index=factory->CreateIndex(); code->Getcode(); code->Setcode(); index->Getindex(); index->Setindex(); code=DataShangA::CreateCode(); index=DataShangA::CreateIndex(); code->Getcode(); code->Setcode(); index->Getindex(); index->Setindex(); return 0; }