1 概念
工厂模式的定义:定义一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体子工厂类当中。这满足创建型模式中所要求的“创建与使用相分离”的特点。
按实际业务场景划分,工厂模式有 3 种不同的实现方式,分别是简单工厂模式、工厂方法模式和抽象工厂模式。
我们把被创建的对象称为“产品”,把创建产品的对象称为“工厂”。如果要创建的产品不多,只要一个工厂类就可以完成,这种模式叫“简单工厂模式”。
在简单工厂模式中创建实例的方法通常为静态(static)方法,因此简单工厂模式(Simple Factory Pattern)又叫作静态工厂方法模式(Static Factory Method Pattern)。
简单来说,简单工厂模式有一个具体的工厂类,可以生成多个不同的产品,属于创建型设计模式。简单工厂模式不在 GoF 23 种设计模式之列。
2 UML图
3 C++示例代码
simple_factory.h
#include <iostream>
class Product {
public:
virtual double GetResult(double a, double b) = 0;
};class ProductA: public Product {
public:
double GetResult(double a, double b) override;
};class ProductB: public Product {
public:
double GetResult(double a, double b) override;
};class ProductC: public Product {
public:
double GetResult(double a, double b) override;
};class ProductD: public Product {
public:
double GetResult(double a, double b) override;
};class Factory {
public:
static Product* GetProduct(int type); // 此处虽然不是强制用static,但是用static更合理,这不需要解释吧
};
simple_factory.cpp
#include <iostream>
#include "simple_factory.h"using namespace std;
double ProductA::GetResult(double a, double b)
{
return a + b;
}double ProductB::GetResult(double a, double b)
{
return a - b;
}double ProductC::GetResult(double a, double b)
{
return a * b;
}double ProductD::GetResult(double a, double b)
{
return a / b;
}Product* Factory::GetProduct(int type)
{
switch (type) {
case 0:
return new ProductA;
case 1:
return new ProductB;
case 2:
return new ProductC;
case 3:
return new ProductD;
}
return nullptr;
}int main()
{
Product *product = Factory::GetProduct(0);
if (product == nullptr) {
cout << "Get product failed" << endl;
return -1;
}
double a = 0.1;
double b = 0.2;
double c = product->GetResult(a, b);cout << c << endl;
return 0;
}
4 总结
简单工厂模式每增加一个产品就要增加一个具体产品类和一个对应的具体工厂类,这增加了系统的复杂度,违背了“开闭原则”。
优点和缺点
优点:
工厂类包含必要的逻辑判断,可以决定在什么时候创建哪一个产品的实例。客户端可以免除直接创建产品对象的职责,很方便的创建出相应的产品。工厂和产品的职责区分明确。
客户端无需知道所创建具体产品的类名,只需知道参数即可。
也可以引入配置文件,在不修改客户端代码的情况下更换和添加新的具体产品类。
缺点:
简单工厂模式的工厂类单一,负责所有产品的创建,职责过重,一旦异常,整个系统将受影响。且工厂类代码会非常臃肿,违背高聚合原则。
使用简单工厂模式会增加系统中类的个数(引入新的工厂类),增加系统的复杂度和理解难度
系统扩展困难,一旦增加新产品不得不修改工厂逻辑,在产品类型较多时,可能造成逻辑过于复杂
简单工厂模式使用了 static 工厂方法,造成工厂角色无法形成基于继承的等级结构。
应用场景
对于产品种类相对较少的情况,考虑使用简单工厂模式。使用简单工厂模式的客户端只需要传入工厂类的参数,不需要关心如何创建对象的逻辑,可以很方便地创建所需产品。