目录
定义
简单工厂模式(Simple Factory Pattern):专门定义一个类(工厂类)来负责创建其他类的实例。可以根据创建方法的参数来返回不同类的实例,被创建的实例通常都具有共同的父类。
简单工厂模式又称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式。
创建型模式(Creational Pattern)对类的实例化过程进行了抽象,能够将软件模块中对象的创建和对象的使用分离。为了使软件的结构更加清晰,外界对于这些对象只需要知道它们共同的接口,而不清楚其具体的实现细节,使整个系统的设计更加符合单一职责原则。
创建型模式在创建什么(What),由谁创建(Who),何时创建(When)等方面都为软件设计者提供了尽可能大的灵活性。
创建型模式隐藏了类的实例的创建细节,通过隐藏对象如何被创建和组合在一起达到使整个系统独立的目的。
使用场景
如果我们希望将一些为数不多的类似的对象的创建和他们的创建细节分离开,也不需要知道对象的具体类型,可以使用简单工厂模式。
举个形象点的例子:例如如果实现计算器的功能时,对于同样的输入数据,可能执行加、减、乘、除,甚至其他的功能。因此可以抽象出一个操作的抽象类或是接口,提供一个统一的处理方法,然后每种操作创建出一个子类出来。而判断具体使用哪个具体的实现类是在工厂类中进行判断的。工厂类始终返回的是这个抽象类,这样如果对原有功能进行更改或是新添加新的功能,也不会对原来的其他类做修改,只编译修改的那个类或是新的类就可以了。
这样就做到了把耦合降到最低,同时也便于维护。
实现方式
在简单工厂模式有三个基本角色:
- Product(抽象的产品角色):它是工厂类所创建对象的父类,封装了所有产品对象共有的方法。
- ConcreteProduct(具体产品角色):继承抽象产品角色,它是简单工厂模式所创建目标,工厂类返回的对象都是该某一具体产品角色。
- Factory (工厂角色) :是简单工厂模式的核心,它负责实现创建所有具体产品的实例的内部逻辑,工厂类可以被外界直接调用,创建所需的产品对象。
类关系如下图所示:
举个计算器使用简单工厂的例子:
头文件部分
#include <iostream>
#include <string>
using namespace std;
抽象产品角色实现
class Operation {
private:
int numberA;
int numberB;
public:
virtual ~Operation() {}
void setNumberA(int a) {
this->numberA = a;
}
void setNumberB(int b) {
this->numberB = b;
}
int getNumberA() {
return numberA;
}
int getNumberB() {
return numberB;
}
virtual int getResult() = 0;
};
具体产品角色的实现
class OperationAdd : public Operation {
public:
int getResult(){
return (getNumberA() + getNumberB());
}
};
class OperationSub : public Operation {
public:
int getResult(){
return (getNumberA() - getNumberB());
}
};
class OperationMul : public Operation {
public:
int getResult(){
return (getNumberA() * getNumberB());
}
};
class OperationDiv : public Operation {
public:
int getResult(){
return (getNumberA() / getNumberB());
}
};
工厂角色的实现
class OperationFactory{
public:
Operation* createOperation(char ch){
Operation *p = NULL;
switch(ch){
case '+': {
p = new OperationAdd();
break;
}
case '-': {
p = new OperationSub();
break;
}
case '*': {
p = new OperationMul();
break;
}
case '/': {
p = new OperationDiv();
break;
}
default: assert(false);
}
return p;
}
};
测试函数编写
int main()
{
OperationFactory factory;
Operation *p = factory.createOperation('+');
p->setNumberA(2);
p->setNumberB(3);
cout << p->getResult()<< endl;
if(p) {
delete p;
p = nullptr;
}
return 0;
}
优点
将对象的创建与使用分离,将对象的创建交给工厂类负责, 而不需要知道其创建细节,一定程度上减少系统的耦合。
客户端无需知道所创建的具体产品类的类名,只要知道具体产品类所对应的参数即可,然后通过工厂类获取。
缺点
工厂类集中了所有产品的创建逻辑,职责过重,一旦有问题会导致整个系统受影响。所以简单工厂模式比较适合产品种类比较少而且增多的概率很低的情况。
如果引入新的具体产品,就会导致去修改工厂类的逻辑,不符合“开闭原则”。