工厂模式

阅读提示(2026-10):本文的字符串分支创建器属于“简单工厂”,并非 GoF 的 Factory Method。新专题用完整可运行程序区分三种结构,见程序设计 01:简单工厂、工厂方法与抽象工厂。原笔记和地址继续保留。

工厂模式:把对象创建逻辑从业务代码里拆出来

工厂模式的目的

工厂模式(Factory Pattern)的核心目的:把对象创建逻辑封装起来,让使用者不用关心具体创建哪个类、怎么创建。

简单说:

不要到处写 if/else + new 具体类,
而是把创建逻辑集中放到 Factory 里。

适合场景:

  1. 根据配置、字符串、枚举创建不同对象。
  2. 对象创建过程比较复杂。
  3. 希望业务代码只依赖抽象接口,而不是依赖一堆具体类。
  4. 后续可能扩展新类型,比如新增一种机器人、传感器、控制器、算法。

和策略模式的关系也很近:策略模式负责“算法可以互换”,工厂模式负责“帮你创建具体策略对象”。

什么时候适合用工厂模式

如果一个对象的创建逻辑很简单,例如:

Robot robot;

那通常没必要引入工厂模式。

但如果创建对象需要根据配置、字符串、枚举、平台类型、传感器类型来决定,或者构造过程包含很多参数、校验、资源初始化,那么工厂模式就会变得有用。

它的目标不是“让代码看起来高级”,而是让业务代码更干净:

业务代码:我要一个 robot。
工厂代码:我来决定具体创建 SpotRobot 还是 UnitreeRobot。

C++ 示例:根据字符串创建不同机器人

下面这个例子里,业务代码只使用 Robot 接口。具体创建 SpotRobot 还是 UnitreeRobot,交给 RobotFactory 决定。

#include <iostream>
#include <memory>
#include <stdexcept>
#include <string>

// 抽象产品:统一接口
class Robot {
public:
virtual ~Robot() = default;
virtual void walk() = 0;
};

// 具体产品 1
class SpotRobot : public Robot {
public:
void walk() override {
std::cout << "Spot robot is walking." << std::endl;
}
};

// 具体产品 2
class UnitreeRobot : public Robot {
public:
void walk() override {
std::cout << "Unitree robot is walking." << std::endl;
}
};

// 工厂:集中管理对象创建逻辑
class RobotFactory {
public:
static std::unique_ptr<Robot> createRobot(const std::string& type) {
if (type == "spot") {
return std::make_unique<SpotRobot>();
}
if (type == "unitree") {
return std::make_unique<UnitreeRobot>();
}
throw std::invalid_argument("Unknown robot type: " + type);
}
};

int main() {
auto robot = RobotFactory::createRobot("spot");
robot->walk();

robot = RobotFactory::createRobot("unitree");
robot->walk();

return 0;
}

这个结构里:

  • Robot 是抽象接口。
  • SpotRobot / UnitreeRobot 是具体类。
  • RobotFactory 负责根据类型创建对象。
  • main() 不需要直接写 new SpotRobot() 或 new UnitreeRobot()。

Python 示例:根据字符串创建不同机器人

Python 里写起来更轻量,可以用字典代替长串 if/elif。

from abc import ABC, abstractmethod


class Robot(ABC):
@abstractmethod
def walk(self):
pass


class SpotRobot(Robot):
def walk(self):
print("Spot robot is walking.")


class UnitreeRobot(Robot):
def walk(self):
print("Unitree robot is walking.")


class RobotFactory:
_registry = {
"spot": SpotRobot,
"unitree": UnitreeRobot,
}

@classmethod
def create_robot(cls, robot_type: str) -> Robot:
robot_cls = cls._registry.get(robot_type)
if robot_cls is None:
raise ValueError(f"Unknown robot type: {robot_type}")
return robot_cls()


if __name__ == "__main__":
robot = RobotFactory.create_robot("spot")
robot.walk()

robot = RobotFactory.create_robot("unitree")
robot.walk()

如果后面要新增机器人类型,只需要新增类,并注册到 _registry:

class BittleRobot(Robot):
def walk(self):
print("Bittle robot is walking.")


RobotFactory._registry["bittle"] = BittleRobot

工厂模式和策略模式怎么配合

策略模式常见写法是:

Context 持有 Strategy 接口
不同 ConcreteStrategy 实现不同算法

但如果策略很多,业务代码里可能会变成:

if (name == "add") {
context.setStrategy(std::make_shared<AddStrategy>());
} else if (name == "sub") {
context.setStrategy(std::make_shared<SubStrategy>());
}

这时就可以用工厂模式把创建策略的逻辑收起来:

StrategyFactory.create("add") -> AddStrategy
StrategyFactory.create("sub") -> SubStrategy

这样业务代码只关心:

我要哪个策略名字。

不关心:

这个策略对应哪个具体类、怎么 new、构造参数是什么。

一句话总结:

策略模式解决“行为怎么替换”,工厂模式解决“对象怎么创建”。

总结

工厂模式的核心不是“工厂”这个名字,而是这件事:

把对象创建逻辑集中管理,让业务代码依赖抽象接口,而不是到处依赖具体类。

它特别适合用在机器人、传感器、控制器、算法模块这类“类型会变多、创建逻辑会变复杂”的场景里。

知识共享许可协议