%%
# 纲要
> 主干纲要、Hint/线索/路标
# Q&A
#### 已明确
#### 待明确
> 当下仍存有的疑惑
**❓<font color="#c0504d"> 有什么问题?</font>**
%%
# 三种工厂模式的区别
- **简单工厂模式**:
- 思路:一个工厂类**根据 "传入==参==数"** 创建不同类型的**具体产品对象**;
- 缺点:**违反开闭原则**,增加新的产品对象时,需要**修改工厂类的代码**。
- **工厂方法模式**:
- 思路:一个**抽象工厂基类**定义**一个 `create` 通用接口**,每种 **==具体工厂子类==** 实现接口,直接负责 **==某一种==具体产品对象** 的创建。
- 优点:
- 增加新的产品对象时,只需**添加新的具体工厂子类**,无需修改既有代码。
- 可形成 "**工厂的继承体系**",不同等级的产品由相应等级的工厂创建,形成产品树和工厂树的对应关系。
- **抽象工厂模式**:
- 思路:在 "工厂方法模式" 的基础上,**一个工厂类负责 "多个相关产品",即==整套 "产品族"== 的构造**(例如同一品牌下的配套设备:车+轮胎+引擎)。
- **抽象工厂基类**定义**多个 `create` 接口**(对应同一族的各个产品),每种 **==具体工厂子类==** 实现各个接口,负责**某一族具体产品对象**的创建。
#### 优缺点对比
- 简单工厂模式不满足 "**开放-封闭**" 原则,将 "**判断创造哪种对象的逻辑**" 与 "**对象创建**" 混合,不够灵活,新增对象时需修改工厂类代码。
- 工厂方法模式将 "**判断创造哪种对象的逻辑**" 与 "**对象创建**" 分离,每种具体工厂类只负责一种具体产品对象的创造,更符合 "**单一职责原则**"。
- 抽象工厂模式下,**一个具体工厂类** 通常作为 "**抽象工厂模式类**" 的成员(`has-a` 关系),而后者则是对 "**一族相关产品**" 的大封装,再进一步对外提供一个 "**大接口**"——创建整个产品家族。
> [!summary]
>
> 实现上,三种方法都基于 "**多态**",返回的是 "**==抽象产品类==**" 的指针,而实际指向 "**具体产品类**" 对象,差异在于:
>
> - **简单工厂模式**:一个工厂生产 **多个产品**,根据传入参数用 if/else 或 switch 控制。
> - **工厂方法模式**:一个工厂生产 **一个特定产品**,新增产品 => 新增工厂类。
> - **抽象工厂模式**:一个工厂生产 **一族相关联的多个产品**,而无需指定具体类。
# 简单工厂模式
<br><br><br>
# 工厂方法模式 Factory Method
**工厂方法模式**(Factory Method)定义了一个 "**==创建对象==**" 的**接口**(抽象类),**由其==具体子类==决定实例化的对象的类型**。
其将 "业务代码" 与 "**实例化具体类**" 的代码解耦,适用于 "**事先不知道需要哪些具体类的情况**"。
> [!NOTE] 工厂模式旨在解决的问题:
>
> 每次 `new` 一个对象是在**针对 "具体类/具体实现" 编程**,这就导致了高耦合性——例如,当**可选的具体类**扩充时,各处涉及 `new` 的代码都需要重新修改。
> **"工厂模式" 封装了通过 `new` 这一 "创建对象" 的过程**,称之为 "**==工厂方法==**",从而进行解耦。
>
<br>
### 工厂方法模式的构成
- **抽象工厂类**(也称 Creator 类):定义了 "**==工厂方法==**" 接口 `factoryMethod` ,该接口由 "**具体工厂类**" 进行实现。
- **具体工厂类**:具体实现 "**工厂方法**",决定实例化对象的具体类型。
- **抽象产品类**:定义 "**产品**" 的 **==共同接口==**。
- **具体产品类**:实现产品接口的具体类。
> [!NOTE] 工厂方法模式的类图
> ![[_attachment/02-开发笔记/16-设计模式/工厂模式.assets/IMG-工厂模式-A8218FB6945B771CDE3EE6BC16D29E9A.png|900]]
<br>
### 示例代码
```cpp
#include <memory>
#include <iostream>
// 披萨品类
enum class PizzaType { Cheese, Veggie, Pepperoni };
// 抽象产品类
class Pizza {
public:
virtual void prepare() const = 0;
virtual ~Pizza() = default;
};
// 具体产品类11: 纽约风格的起司披萨
class NYStyleCheesePizza: public Pizza {
public:
void prepare() const override {
std::cout << "Preparing NYStyleCheese Pizza" << std::endl;
}
};
// 具体产品类12: 纽约风格的蔬菜披萨
class NYStyleVeggiePizza: public Pizza {
public:
void prepare() const override {
std::cout << "Preparing NYStyleVeggie Pizza" << std::endl;
}
};
// 具体产品类13: 纽约风格的胡椒披萨
class NYStylePepperoniPizza: public Pizza {
public:
void prepare() const override {
std::cout << "Preparing NYStylePepperoni Pizza" << std::endl;
}
};
// 具体产品类21: 芝加哥风格的起司披萨
class ChicagoStyleCheesePizza: public Pizza {
void prepare() const override {
std::cout << "Preparing ChicagoStyleCheese Pizza" << std::endl;
}
};
// 具体产品类22: 芝加哥风格的蔬菜披萨
class ChicagoStyleVeggiePizza: public Pizza {
void prepare() const override {
std::cout << "Preparing ChicagoStyleVeggie Pizza" << std::endl;
}
};
// 具体产品类23: 芝加哥风格的胡椒披萨
class ChicagoStylePepperoniPizza: public Pizza {
public:
void prepare() const override {
std::cout << "Preparing ChicagoStylePepperoni Pizza" << std::endl;
}
};
// 抽象工厂类
class PizzaStore {
public:
virtual std::shared_ptr<Pizza> orderPizza(PizzaType type) const = 0;
virtual std::shared_ptr<Pizza> createPizza(PizzaType type) const = 0; // 工厂方法 Factory Method.
virtual ~PizzaStore() = default;
};
// 具体工厂类1: 纽约风味披萨店
class NYStylePizzaStore : public PizzaStore {
public:
std::shared_ptr<Pizza> orderPizza(PizzaType style) const {
std::shared_ptr<Pizza> pizza = createPizza(style);
if (pizza) {
pizza->prepare(); // 对抽象产品类执行op, 与具体类型无关.
} else {
std::cout << "No such kind of pizza" << std::endl;
}
return pizza;
}
// 工厂方法: 封装创建对象的过程, 决定具体创建的对象类型.
// 这里是 "参数化工厂方法", 根据传入参数来选择具体创建类型.
std::shared_ptr<Pizza> createPizza(PizzaType style) const {
// 多态
std::shared_ptr<Pizza> pizza;
switch (style) {
case PizzaType::Cheese:
pizza = std::make_shared<NYStyleCheesePizza>();
break;
case PizzaType::Veggie:
pizza = std::make_shared<NYStyleVeggiePizza>();
break;
case PizzaType::Pepperoni:
pizza = std::make_shared<NYStylePepperoniPizza>();
break;
default:
pizza = nullptr;
}
return pizza;
}
};
// 具体工厂类2: 芝加哥风味披萨店
class ChicagoStylePizzaStore : public PizzaStore {
public:
std::shared_ptr<Pizza> orderPizza(PizzaType style) const {
std::shared_ptr<Pizza> pizza = createPizza(style);
pizza->prepare(); // 对抽象产品类执行op, 与具体类型无关.
return pizza;
};
// 工厂方法: 封装创建对象的过程, 决定具体创建的对象类型.
// 这里是 "参数化工厂方法", 根据传入参数来选择具体创建类型.
std::shared_ptr<Pizza> createPizza(PizzaType style) const {
// 多态
std::shared_ptr<Pizza> pizza;
switch (style) {
case PizzaType::Cheese:
pizza = std::make_shared<ChicagoStyleCheesePizza>();
break;
case PizzaType::Veggie:
pizza = std::make_shared<ChicagoStyleVeggiePizza>();
break;
case PizzaType::Pepperoni:
pizza = std::make_shared<ChicagoStylePepperoniPizza>();
break;
default:
pizza = nullptr;
}
return pizza;
}
};
int main() {
NYStylePizzaStore nyStore;
ChicagoStylePizzaStore chicagoStore;
nyStore.orderPizza(PizzaType::Cheese);
chicagoStore.orderPizza(PizzaType::Cheese);
std::cout << std::endl;
nyStore.orderPizza(PizzaType::Veggie);
chicagoStore.orderPizza(PizzaType::Veggie);
std::cout << std::endl;
nyStore.orderPizza(PizzaType::Pepperoni);
chicagoStore.orderPizza(PizzaType::Pepperoni);
std::cout << std::endl;
return 0;
}
```
<br><br><br>
# 抽象工厂模式 Abstract Factory
抽象工厂模式用于 **需要"创建==一系列 "相关" 产品==**" 的场景——**"一个工厂" 提供多个 `create` 接口,各个 `create` 接口创建的不同产品属于 "同一族相关产品"**。
### 抽象工厂模式的构成
- **抽象工厂类**:定义 "**==一系列工厂方法==**": `createXXX()` 接口,各接口所创建的产品属于 "**同一族**"。
- **具体工厂类**:具体实现 "**工厂方法**",决定实例化对象的具体类型。
- **抽象产品类**:定义 "**产品**" 的 **==共同接口==**。
- **具体产品类**:实现产品接口的具体类。
![[_attachment/02-开发笔记/16-设计模式/工厂模式.assets/IMG-工厂模式-BFEB983A240363AD7F4A3D3368884E42.png|946]]
<br><br>
<br><br>
# Buffer
## 闪念
> sudden idea
## 候选资料
> Read it later
# ♾️参考资料
# Footnotes