工厂模式

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

工厂模式的目的

工厂模式(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、构造参数是什么。

一句话总结:

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

总结

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

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

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

algorithms axis-angle bode calibration chrome cmake cmakelists cnn colcon conan control cpp cpu d435i data_struct db design-pattern dots economics eigen factory-pattern fcpx figure finance forge fov gazebo gdb git gnu ibus interest isaac gym isaaclab kdl latex launch learning-notes legged locomotion legged-robot life linux mac math matlab matrix memory mlp money motor moveit mpc network ocs2 ode operator optimal algorithm optimal-control perf performance personal-finance ppo profiling python qos realsense rnn robot robotics ros ros2 rtb security shell simulation stl thread tools twist ubuntu uml unitree urdf vae valgrind vcxsrv velocity vim web wifi work wsl 中文输入 交叉编译 依赖管理 分支管理 四足机器人 强化学习 机器人视觉 构建系统 深度学习 深度相机 点云 版本控制 神经网络 输入法 配置类
知识共享许可协议