工厂设计模式,顾名思义,就是用来生产对象的,在JVAA或C++中,万物皆对象,这些对象都需要创建,如果创建的时候直接new该对象,就会对该对象耦合严重,假如我们要更换对象,所有new对象的地方都需要修改一遍,这显然违背了软件设计的开闭原则,如果我们使用工厂来生产对象,我们就只和工厂打交道就可以了,彻底和对象解耦,如果要更换对象,直接在工厂里更换该对象即可,达到了与对象解耦的目的;所以说,工厂模式最大的优点就是:解耦。
现在有这样一个场景,假如小米公司售卖手机,有很多种类的手机,如红米,小米等等,公司只需要从工厂把客户需要的手机拿过来卖就好了,而不需要去关心手机是怎么做出来的,反正最后需要的都是手机。下面用具体代码来描述这一过程。
1.简单工厂模式的实现
简单工厂模式是由一个工厂对象根据收到的消息决定要创建哪一个类的对象实例。对象创建的逻辑是由一个工厂来实现的。简单工厂类负责创建的对象比较少,客户端唯一需要知道的具体子类就是工厂子类。除了这点,基本是达到了依赖倒转原则的要求。对于如何创建对象(逻辑)不关心。简单工厂模式很容易违反高内聚低耦合的原则,因此一般只在很简单的情况下使用。
#include <iostream> using namespace std; class AbstractProduct { public: virtual ~AbstractProduct() {} virtual void Operation() = 0; };
class ProductA : public AbstractProduct { public: void Operation() { cout << "我生产小米手机" << endl;} };
class ProductB : public AbstractProduct { public: void Operation() { cout << "我生产红米手机" << endl; } }; class Factory { public: AbstractProduct* createProduct(char product) { AbstractProduct* ap = NULL; switch(product) { case 'A': ap = new ProductA(); break; case 'B': ap = new ProductB(); break; } return ap; } }; class Company { public: AbstractProduct *phone; Company(AbstractProduct *phone){ this->phone=phone; } void sell(){ phone->Operation(); cout<<"拿到手机,售卖手机...."<<endl; } }; int main() { Factory* f = new Factory(); AbstractProduct* apa = f->createProduct('A'); AbstractProduct* apb = f->createProduct('B'); Company *a=new Company(apa); a->sell(); Company *b=new Company(apb); b->sell(); delete apa; delete apb; delete f; return 0; } |
2.工厂方法模式的实现
工厂方法模式定义了一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到子类。工厂模式基本与简单工厂模式差不多,上面可以看出,每次添加一个产品子类都必须在工厂类中添加一个判断分支,这样违背了开放-封闭原则。而工厂模式创建对象的接口,让子类决定具体实例化的对象,把简单的内部逻辑判断移到了客户端。工厂方法模式克服了简单工厂所违背的开闭原则的缺点,又保持了封装对象创建过程的优点。扩展性高,想要增加一个产品,只要扩展一个工厂类就可以。
#include <iostream> using namespace std;
class Product { public: virtual ~Product(){} virtual void Operation() = 0; };
class ConcreteProductA : public Product { public: void Operation() { cout << "我生产小米手机" << endl; } };
class ConcreteProductB : public Product { public: void Operation() { cout << "我生产红米手机" << endl; } };
class Creator{ public: virtual Product* FactoryMethod() = 0; virtual ~Creator(){} };
class ConcreteCreatorA : public Creator { public: Product* FactoryMethod() { return new ConcreteProductA(); } };
class ConcreteCreatorB : public Creator { public: Product* FactoryMethod() { return new ConcreteProductB(); } }; class Company { public: Product *phone; Company(Product *phone){ this->phone=phone; } void sell(){ phone->Operation(); cout<<"拿到手机,售卖手机...."<<endl; } }; int main() { Creator* ca = new ConcreteCreatorA(); Creator* cb = new ConcreteCreatorB(); Product* pa = ca->FactoryMethod(); Product* pb = cb->FactoryMethod(); Company *a=new Company(pa); a->sell(); Company *b=new Company(pb); b->sell(); return 0; } |
3.抽象工厂模式
此外还有一种抽象工厂模式,适用于多种类的产品,比如小米公司不仅售卖手机,还售卖与手机配套的耳机,这样我们就可以写一个抽象工厂来创建这一系类产品,对于不同系类的产品进行不同的接口实现。抽象工厂可以解决一系列的产品生产的需求,对于大批量,多系列的产品,用抽象工厂可以更好的管理和扩展。抽象工厂模式其实是简单工厂模式和工厂方法模式的组合。
这里就不具体描述简单写一下核心代码
class AbstractFactory { public: virtual AbstractProductA* CreateProductA() = 0; virtual AbstractProductB* CreateProductB() = 0; virtual ~AbstractFactory(){} };
class ConcreteFactory1 : public AbstractFactory { public: ProductA1* CreateProductA() { return new ProductA1(); } ProductB1* CreateProductB() { return new ProductB1(); } };
class ConcreteFactory2 : public AbstractFactory { public: ProductA2* CreateProductA() { return new ProductA2(); } ProductB2* CreateProductB() { return new ProductB2(); } }; |
这里的具体产品的创建的方式和上述简单工厂一致。
优点
1.封装了产品的创建,使得不需要知道具体是哪种产品,只需要知道是哪个工厂就行了。
2.可以支持不同类型的产品,使得模式灵活性更强。
3.可以非常方便的使用一族中间的不同类型的产品。
缺点
1.结构太过臃肿,如果产品类型比较多,或者产品族类比较多,就会非常难于管理。
2.每次如果添加一组产品,那么所有的工厂类都必须添加一个方法,这样违背了开放-封闭原则。所以一般适用于产品组合产品族变化不大的情况。