工厂模式:把对象创建逻辑从业务代码里拆出来
工厂模式的目的
工厂模式(Factory Pattern)的核心目的:把对象创建逻辑封装起来,让使用者不用关心具体创建哪个类、怎么创建。
简单说:
不要到处写 if/else + new 具体类, 而是把创建逻辑集中放到 Factory 里。
|
适合场景:
- 根据配置、字符串、枚举创建不同对象。
- 对象创建过程比较复杂。
- 希望业务代码只依赖抽象接口,而不是依赖一堆具体类。
- 后续可能扩展新类型,比如新增一种机器人、传感器、控制器、算法。
和策略模式的关系也很近:策略模式负责“算法可以互换”,工厂模式负责“帮你创建具体策略对象”。
什么时候适合用工厂模式
如果一个对象的创建逻辑很简单,例如:
那通常没必要引入工厂模式。
但如果创建对象需要根据配置、字符串、枚举、平台类型、传感器类型来决定,或者构造过程包含很多参数、校验、资源初始化,那么工厂模式就会变得有用。
它的目标不是“让代码看起来高级”,而是让业务代码更干净:
业务代码:我要一个 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; };
class SpotRobot : public Robot { public: void walk() override { std::cout << "Spot robot is walking." << std::endl; } };
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、构造参数是什么。
|
一句话总结:
策略模式解决“行为怎么替换”,工厂模式解决“对象怎么创建”。
总结
工厂模式的核心不是“工厂”这个名字,而是这件事:
把对象创建逻辑集中管理,让业务代码依赖抽象接口,而不是到处依赖具体类。
它特别适合用在机器人、传感器、控制器、算法模块这类“类型会变多、创建逻辑会变复杂”的场景里。