上一篇文章写了 《工程实践:C++接口设计指北》
主要写了用C++写第三库,如何设计接口的问题,其中用到了工厂模式,在此之前,一直不太明白《设计模式》在实际开发中的应用。
现在正好被我逮到了,以此为例,深入学习一下!
设计模式之工厂模式
工厂顾名思义就是创建产品,根据产品是具体产品还是具体工厂可分为简单工厂模式和工厂方法模式,根据工厂的抽象程度可分为工厂方法模式和抽象工厂模式。该模式用于封装和管理对象的创建,是一种创建型模式。
工厂设计模式是为了将对象的创建与使用进行分离 。(这段话是本文的重点)
在上文,我们接口设计主要目的也是这个;接口是实现多重继承的途径(这个知识点,在面试的时候,一定会被问道多态和虚函数),而生成遵循某个接口的对象的典型方法就是工厂方法的设计模式,这和直接调用构造函数不同,我们在工厂对象中调用的是创建函数,而该工厂对象将生成接口的某个实现对象。
在理论层面上,通过这种方法我们达到接口和代码实现分离的目标。
为什么使用工厂模式
1.工厂设计模式是为了将对象的创建与使用进行分离
这句话第二次被提到。
其实这句话,再抽象一下就是降低模块间的耦合度。
我们举个例子:
现在有俩个模块:模块A、模块B
其中模块A有很多子模块继承于模块A,模块A_1、模块A_2…模块A_n,这些模块都有一个共同的接口。
此时,模块B要调用模块A的子模块的方法,需要写成module_A1->interface()或者 module_An->interface();
这时候模块B中充满了模块A子模块的实例,两个模块高度耦合,而且使用接口的地方代码重复率很高。
我们想到了改进,使用多态,mode *A = new module_A1(); A->interface();虽然这种情况解决了模块B中多个模块A子模块的问题,只要一个模块A实例,降低了耦合度。
但是还有一个问题,那就是模块B每次调用都还要知道,具体实例化哪个A的子模块,同时模块A添加修改了子模块,模块B也要修改;
但是模块B并不想操心那么多,于是模块B说:“我只想无脑用这个接口罢了”,此时模块A说:“没问题,这个交给我来解决,以后你只要调用下面这个接口,其它交给我来办”,这是模块B开心的笑了,嗯嗯,这样多简单啊。
Factory* factory = new Factory();
factory->Create(xxx)->interface();
此时模块A和模块B之间的耦合度基本很小了,上面的factory,就是我们常说的工厂模式了,工厂会根据参数自动创建对应的模块A子模块实例,它主要是用来减少两个模块间的耦合度的,调用者不需要管你是怎么创建的对象,调用者只负责拿来用就行。
2.其他好处
减少代码的维护难度,增加代码的可阅读性。
简单工厂模式
简单工厂模式举个直白的例子就是,好比一个手机制造工厂,里面有几条手机制造生产线,我们只要给了对应的材料,就能制造出对应的手机。
代码示例:
#include <iostream>
using namespace std;
enum phoneType {
miType = 0,
huaweiType,
oppoType
};
class phone {
public:
virtual void show()=0;
};
class mi:public phone{
public:
void show() {
cout<<"mi phone create"<<endl;
}
};
class huawei: public phone {
public:
void show() {
cout<<"huawei phone create"<<endl;
}
};
class oppo: public phone {
public:
void show() {
cout<<"oppo phone create"<<endl;
}
};
#if 1
class Factory {
public:
phone* createPhone(enum phoneType type) {
if(type == miType) {
return new mi();
} else if (type == huaweiType) {
return new huawei();
} else if (type == oppoType){
return new oppo();
} else {
return NULL;
}
}
};
#endif
int main() {
Factory *f = new Factory(