创建型模式
简单工厂模式
模式定义
简单工厂模式(Simple Factory Pattern),又称为静态工厂方法(Static Factory Method)模式。
在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。
模式结构
简单工厂模式包含以下角色:
- Factory: 负责实现创建所有实例的内部逻辑。
- Product: 所创建的所有对象的父类,负责描述所有实例所共有的公共接口。
- ConcreteProduct: 创建目标,所有创建的对象都充当这个角色的某个具体类的实例。
示例代码
#include <iostream>
#include <memory>
class Product {
public:
Product() = default;
virtual ~Product() = default;
virtual void use() = 0;
};
using ProductPtr = std::shared_ptr<Product>;
class ConcreteProductA : public Product {
public:
ConcreteProductA() = default;
~ConcreteProductA() override = default;
void use() override {
std::cout << "use ConcreteProductA" << std::endl;
}
};
class ConcreteProductB : public Product {
public:
ConcreteProductB() = default;
~ConcreteProductB() override = default;
void use() override {
std::cout << "use ConcreteProductB" << std::endl;
}
};
class Factory {
public:
static ProductPtr createProduct(std::string_view name) {
if (name == "A") {
return std::make_shared<ConcreteProductA>();
} else {
return std::make_shared<ConcreteProductB>();
}
}
};
int main() {
ProductPtr a = Factory::createProduct("A");
ProductPtr b = Factory::createProduct("B");
a->use(); // use ConcreteProductA
b->use(); // use ConcreteProductB
return 0;
}
优点
- 将对象的创建和对象本身业务处理分离可以降低系统的耦合度,使得两者修改起来都相对容易。
- 客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可,对于一些复杂的类名,通过简单工厂模式可以减少使用者的记忆量。
缺点
- 由于工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响。
- 系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护。
- 简单工厂模式由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构。
适用环境
- 工厂类负责创建的对象比较少。
- 客户端只知道传入工厂类的参数,对于如何创建对象不关心。
工厂方法模式
模式定义
工厂方法模式(Factory Method Pattern)又称为工厂模式,也叫虚拟构造器(Virtual Constructor)模式或者多态工厂(Polymorphic Factory)模式。
在工厂方法模式中,工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象。
模式结构
工厂方法包含以下角色:
- Product:抽象产品
- ConcreteProduct:具体产品
- Factory:抽象工厂
- ConcreteFactory:具体工厂
示例代码
示例代码对应的结构图如下:
#include <iostream>
#include <memory>
/* Product */
class Log {
public:
Log() = default;
virtual ~Log() = default;
virtual void writeLog() = 0;
};
using LogPtr = std::shared_ptr<Log>;
/* ConcreteProduct */
class FileLog : public Log {
public:
FileLog() = default;
~FileLog() override = default;
void writeLog() override {
std::cout << "write file log" << std::endl;
}
};
/* ConcreteProduct */
class DatabaseLog : public Log