提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
常写C++代码的人一定对于工厂模式不陌生,今天这篇文章就介绍下几种常见的工厂模式并说明使用场景
一、什么是工厂模式
简而言之,工厂模式是一种设计模式,是对开闭原则编程的一种展现。
二、介绍
所有的示例代码基于C++17版本,如果你用了C++11,就会报错,C++11没有std::make_unique这个方法(在memory头文件里)。
1.简单工厂
#include <iostream>
#include <memory>
class Product {
public:
virtual void show() = 0;
virtual ~Product() = default;
};
class ProductA : public Product {
public:
void show() override {
std::cout << "ProductA" << std::endl;
}
};
class ProductB : public Product {
public:
void show() override {
std::cout << "ProductB" << std::endl;
}
};
class Factory {
public:
static std::unique_ptr<Product> createProduct(char type) {
switch (type) {
case 'A':
return std::make_unique<ProductA>();
case 'B':
return std::make_unique<ProductB>();
default:
return nullptr;
}
}
};
main.cpp
#include "Factory.h"
int main(){
auto produce1 = Factory::createProduct('A');
produce1->show();
auto produce2 = Factory::createProduct('B');
produce2->show();
return 0;
}
特点:
简单工厂模式定义了一个工厂类,通过工厂类的静态方法来创建不同的对象
优点:
使用者只需要知道工厂类的名称和参数,不需要了解具体的构造过程
缺点:
增加新产品时需要修改工厂类,违反了开闭原则(对扩展开放,对修改关闭)
2.工厂方法模式
Factory.h
#include <iostream>
#include <memory>
class Product {
public:
virtual void show() = 0;
virtual ~Product() = default;
};
class ProductA : public Product {
public:
void show() override {
std::cout << "ProductA" << std::endl;
}
};
class ProductB : public Product {
public:
void show() override {
std::cout << "ProductB" << std::endl;
}
};
class Factory {
public:
virtual std::unique_ptr<Product> createProduct() = 0;
virtual ~Factory() = default;
};
class FactoryA : public Factory {
public:
std::unique_ptr<Product> createProduct() override {
return std::make_unique<ProductA>();
}
};
class FactoryB : public Factory {
public:
std::unique_ptr<Product> createProduct() override {
return std::make_unique<ProductB>();
}
};
main.cpp
#include "Factory.h"
int main(){
auto factoryA = std::make_unique<FactoryA>();
auto productA = factoryA->createProduct();
productA->show();
auto factoryB = std::make_unique<FactoryB>();
auto productB = factoryB->createProduct();
productB->show();
return 0;
}
特点:
工厂方法模式将对象的创建延迟到子类中,每一个具体产品对应一个具体工厂
优点:
增加新产品时,只需增加一个具体工厂类,不需要修改工厂类,符合开闭原则
缺点:
类的数量增加,使得系统更加复杂
3.抽象工厂
Factory.h
#include <iostream>
#include <memory>
class AbstractProductA {
public:
virtual void show() = 0;
virtual ~AbstractProductA() = default;
};
class AbstractProductB {
public:
virtual void show() = 0;
virtual ~AbstractProductB() = default;
};
class ProductA1 : public AbstractProductA {
public:
void show() override {
std::cout << "ProductA1" << std::endl;
}
};
class ProductA2 : public AbstractProductA {
public:
void show() override {
std::cout << "ProductA2" << std::endl;
}
};
class ProductB1 : public AbstractProductB {
public:
void show() override {
std::cout << "ProductB1" << std::endl;
}
};
class ProductB2 : public AbstractProductB {
public:
void show() override {
std::cout << "ProductB2" << std::endl;
}
};
class AbstractFactory {
public:
virtual std::unique_ptr<AbstractProductA> createProductA() = 0;
virtual std::unique_ptr<AbstractProductB> createProductB() = 0;
virtual ~AbstractFactory() = default;
};
class Factory1 : public AbstractFactory {
public:
std::unique_ptr<AbstractProductA> createProductA() override {
return std::make_unique<ProductA1>();
}
std::unique_ptr<AbstractProductB> createProductB() override {
return std::make_unique<ProductB1>();
}
};
class Factory2 : public AbstractFactory {
public:
std::unique_ptr<AbstractProductA> createProductA() override {
return std::make_unique<ProductA2>();
}
std::unique_ptr<AbstractProductB> createProductB() override {
return std::make_unique<ProductB2>();
}
};
main.cpp
#include "Factory.h"
int main(){
auto factory1 = std::make_unique<Factory1>();
auto productA1 = factory1->createProductA();
auto productB1 = factory1->createProductB();
productA1->show();
productB1->show();
auto factory2 = std::make_unique<Factory2>();
auto productA2 = factory2->createProductA();
auto productB2 = factory2->createProductB();
productA2->show();
productB2->show();
return 0;
}
特点:
抽象工厂模式用于创建一系列相关或相互依赖的对象。抽象工厂定义了多个产品的创建接口,而具体工厂实现了这些接口
优点:
可以创建一组相关或依赖的对象,而不需要指定它们的具体类
缺点:
增加新产品时,需要修改抽象工厂和具体工厂,复杂度较高
使用场景
简单工厂模式:
适用于产品种类不多且不频繁变动的场景,但不符合开闭原则
工厂方法模式:
适用于产品种类多且经常变动的场景,每增加一个产品只需要增加一个对应的工厂,符合开闭原则
抽象工厂模式:
适用于创建一系列相互依赖的产品对象的场景,但增加新的产品族时,改动大,符合开闭原则
总结
1、根据个人的场景决定选用哪种方法,除非必要尽量不要使用简单工厂,违反开闭原则,容易引发问题