工厂模式(Factory Pattern)完整详解

工厂模式(Factory Pattern)完整详解

工厂模式是软件开发中最常用的创建型设计模式 ,核心思想是将「对象的创建」与「对象的使用」完全解耦

客户端无需关心对象如何实例化、依赖如何组装,只需要通过「工厂」获取目标对象,极大降低代码耦合,同时满足开闭原则、单一职责原则等设计规范。

工厂模式主要分为3 种形态,复杂度从低到高依次为:

  1. 简单工厂模式(静态工厂模式)
  2. 工厂方法模式
  3. 抽象工厂模式

其中工厂方法、抽象工厂属于GOF 23种经典设计模式,简单工厂是其基础简化版,工程中也极为常用。


一、简单工厂模式(Simple Factory)

1. 核心定义

又称静态工厂模式 ,由一个统一的工厂类 ,根据传入的参数/类型,动态创建不同的具体产品对象,客户端不直接new对象。

注意:简单工厂不属于GOF 23种设计模式,但它是理解工厂模式的基础。

2. 核心角色

角色 作用
抽象产品(Product) 定义所有产品的公共接口/父类
具体产品(ConcreteProduct) 实现抽象产品,是工厂创建的目标对象
工厂类(Factory) 核心类,根据参数判断并创建具体产品
客户端(Client) 调用工厂获取产品,不直接创建产品

3. 代码示例(Python)

以「生产不同形状」为例:

python 复制代码
# 1. 抽象产品:形状接口
class Shape:
    def draw(self):
        pass

# 2. 具体产品:圆形、矩形
class Circle(Shape):
    def draw(self):
        print("绘制圆形")

class Rectangle(Shape):
    def draw(self):
        print("绘制矩形")

# 3. 简单工厂类
class ShapeFactory:
    @staticmethod
    def create_shape(shape_type):
        if shape_type == "circle":
            return Circle()
        elif shape_type == "rectangle":
            return Rectangle()
        else:
            raise ValueError("不支持的形状类型")

# 4. 客户端使用
if __name__ == "__main__":
    # 客户端只调用工厂,不new具体类
    shape1 = ShapeFactory.create_shape("circle")
    shape1.draw()

    shape2 = ShapeFactory.create_shape("rectangle")
    shape2.draw()

4. 优点

  1. 实现创建与使用分离,客户端无需关注对象创建细节
  2. 代码简洁,使用成本极低
  3. 统一管理对象创建,便于维护

5. 缺点

  1. 违反开闭原则:新增产品必须修改工厂类的判断逻辑
  2. 工厂类职责过重,所有产品创建逻辑耦合在一起
  3. 产品种类过多时,工厂类代码会极度臃肿

6. 适用场景

  • 产品种类少且稳定,几乎不需要扩展
  • 简单业务场景,追求快速实现

二、工厂方法模式(Factory Method)

1. 核心定义

对简单工厂的升级:定义抽象工厂接口,每个具体产品对应一个专属工厂子类 ,对象实例化推迟到子类实现。

遵循开闭原则:新增产品时,只需新增产品类+对应工厂类,无需修改原有代码。

2. 核心角色

角色 作用
抽象产品(Product) 产品公共接口
具体产品(ConcreteProduct) 实现抽象产品
抽象工厂(Factory) 定义创建产品的接口方法
具体工厂(ConcreteFactory) 实现抽象工厂,只创建一种具体产品
客户端(Client) 依赖抽象工厂,调用方法获取产品

3. 代码示例(Python)

python 复制代码
# 1. 抽象产品
class Shape:
    def draw(self):
        pass

# 2. 具体产品
class Circle(Shape):
    def draw(self):
        print("绘制圆形")

class Rectangle(Shape):
    def draw(self):
        print("绘制矩形")

# 3. 抽象工厂
class ShapeFactory:
    def create_shape(self):
        pass

# 4. 具体工厂:每个产品对应一个工厂
class CircleFactory(ShapeFactory):
    def create_shape(self):
        return Circle()

class RectangleFactory(ShapeFactory):
    def create_shape(self):
        return Rectangle()

# 5. 客户端使用
if __name__ == "__main__":
    # 用圆形工厂创建圆形
    circle_factory = CircleFactory()
    circle = circle_factory.create_shape()
    circle.draw()

    # 用矩形工厂创建矩形
    rect_factory = RectangleFactory()
    rect = rect_factory.create_shape()
    rect.draw()

4. 优点

  1. 严格遵循开闭原则:新增产品只需新增类,不修改旧代码
  2. 单一职责原则:每个工厂只负责创建一种产品,逻辑清晰
  3. 客户端依赖抽象,不依赖具体类,耦合度极低

5. 缺点

  1. 类数量爆炸式增长:每加一个产品,就要加一个工厂类
  2. 实现复杂度高于简单工厂

6. 适用场景

  • 产品种类多,且需要频繁扩展
  • 希望代码严格遵循设计原则,便于长期维护
  • 典型应用:JDBC 数据库连接、日志框架不同实现切换

三、抽象工厂模式(Abstract Factory)

1. 核心定义

工厂方法的进阶,用于创建一系列相关/相互依赖的产品(产品族) ,而非单个产品。

一个工厂可以生产多个关联产品,保证产品之间的兼容性。

产品族:同一品牌下的多款产品(如美的工厂生产空调+冰箱;格力工厂生产空调+冰箱)

产品等级:同一品类的不同品牌(如美的空调、格力空调)

2. 核心角色

角色 作用
抽象产品族 定义多个产品的接口(如空调、冰箱)
具体产品族 实现抽象产品族,属于同一品牌
抽象工厂 定义创建整个产品族的接口
具体工厂 实现抽象工厂,生产一整套关联产品
客户端 依赖抽象工厂,获取整套产品

3. 代码示例(Python)

以「家电工厂(生产空调+冰箱)」为例:

python 复制代码
# 1. 抽象产品族:空调、冰箱
class AirConditioner:
    def cool(self):
        pass

class Refrigerator:
    def freeze(self):
        pass

# 2. 具体产品族:美的系列、格力系列
class MediaAirConditioner(AirConditioner):
    def cool(self):
        print("美的空调制冷")

class MediaRefrigerator(Refrigerator):
    def freeze(self):
        print("美的冰箱冷冻")

class GreeAirConditioner(AirConditioner):
    def cool(self):
        print("格力空调制冷")

class GreeRefrigerator(Refrigerator):
    def freeze(self):
        print("格力冰箱冷冻")

# 3. 抽象工厂:生产整套家电
class ApplianceFactory:
    def create_air_conditioner(self):
        pass
    def create_refrigerator(self):
        pass

# 4. 具体工厂
class MediaFactory(ApplianceFactory):
    def create_air_conditioner(self):
        return MediaAirConditioner()
    def create_refrigerator(self):
        return MediaRefrigerator()

class GreeFactory(ApplianceFactory):
    def create_air_conditioner(self):
        return GreeAirConditioner()
    def create_refrigerator(self):
        return GreeRefrigerator()

# 5. 客户端使用
if __name__ == "__main__":
    # 美的工厂生产整套美的家电
    media_factory = MediaFactory()
    media_ac = media_factory.create_air_conditioner()
    media_fridge = media_factory.create_refrigerator()
    media_ac.cool()
    media_fridge.freeze()

    # 格力工厂生产整套格力家电
    gree_factory = GreeFactory()
    gree_ac = gree_factory.create_air_conditioner()
    gree_fridge = gree_factory.create_refrigerator()
    gree_ac.cool()
    gree_fridge.freeze()

4. 优点

  1. 强制约束产品族兼容性,避免不匹配的产品组合
  2. 遵循开闭原则,切换产品族只需更换工厂
  3. 统一管理关联产品,代码结构清晰

5. 缺点

  1. 扩展产品等级极难:新增一个产品(如洗衣机),所有工厂都要修改
  2. 复杂度最高,设计成本高

6. 适用场景

  • 系统中有多个产品族,且产品族内产品相互关联
  • 需要保证产品配套使用,避免混用
  • 典型应用:UI组件库(不同主题的按钮+输入框+弹窗)、数据库不同方言适配

四、三种工厂模式核心对比

对比维度 简单工厂 工厂方法 抽象工厂
设计原则 违反开闭原则 遵循开闭原则 遵循开闭原则
工厂职责 一个工厂造所有产品 一个工厂造一种产品 一个工厂造一族产品
类数量 最少 较多 最多
复杂度
扩展难度 难(改工厂) 易(加类) 产品族易扩展,产品等级难扩展
核心定位 快速实现 单产品灵活扩展 多关联产品族管理

五、工厂模式的核心价值

  1. 解耦创建与使用:客户端只负责用对象,不负责造对象
  2. 统一创建逻辑 :避免代码中大量new语句,便于统一修改
  3. 满足设计原则:降低耦合,提高代码可维护性、可扩展性
  4. 隐藏实现细节:复杂对象的依赖注入、初始化逻辑对客户端透明

六、实际工程应用

  1. Spring 框架BeanFactoryApplicationContext 底层大量使用工厂模式创建Bean
  2. JDBCDriverManager 获取Connection,不同数据库驱动对应不同实现
  3. 日志框架:SLF4J 通过工厂适配 Logback、Log4j 等不同日志实现
  4. UI框架:不同主题/平台的组件创建(如移动端、PC端组件)

作为图像算法工程师(CV/医疗AI/工业视觉) ,工厂模式是工程化落地、多模型管理、实验迭代、跨平台部署最常用、最实用的设计模式,没有之一。

结合日常做的目标检测(YOLOv8)、分割、医疗影像算法、模型部署(ONNX/TensorRT)、实验对比 场景,直接讲:什么时候用 + 怎么写代码 + 工程收益


一、图像处理中,什么时候必用工厂模式?

只要出现下面任意一种情况,用工厂模式直接让代码清爽10倍:

  1. 同时维护多个模型
    YOLOv5/YOLOv8/RT-DETR/自定义检测模型、U-Net/DeepLab分割模型,快速切换对比效果。
  2. 同一任务有多种实现
    不同NMS(普通NMS/DIoU NMS/Soft NMS)、不同预处理(医疗影像归一化/自然图像归一化)、不同后处理。
  3. 跨平台/跨推理引擎部署
    同一套业务逻辑,切换 ONNX Runtime / TensorRT / OpenVINO / RKNN 推理。
  4. 实验迭代频繁
    新加一个算法/模型,不改业务代码,只加新类。
  5. 模块化SDK封装
    给前端/业务层调用,隐藏模型加载、推理、预处理细节。
  6. 医疗AI/工业视觉多任务
    舌诊检测、尿液分析、缺陷检测等多任务统一调度。

二、结合CV实战:三种工厂怎么用?

下面全是你日常写推理代码的真实场景,Python实现,可直接放进项目。

场景1:简单工厂 → 快速切换多个检测模型(最常用)

适用 :你有YOLOv8、RT-DETR、自定义模型,想一行代码切换,不用到处改new Model()

核心思路

一个工厂类,根据模型名称,返回对应的模型推理实例。

python 复制代码
import cv2
import numpy as np

# ------------------------------
# 1. 抽象产品:模型推理基类
# ------------------------------
class Detector:
    def infer(self, img: np.ndarray) -> list:
        """模型推理接口"""
        raise NotImplementedError

# ------------------------------
# 2. 具体产品:不同检测模型
# ------------------------------
class YOLOv8Detector(Detector):
    def __init__(self):
        # 加载YOLOv8 onnx/trt模型
        print("加载 YOLOv8 检测模型")
    
    def infer(self, img):
        print("YOLOv8 推理完成")
        return [{"box": [10,20,100,200], "score":0.95}]

class RTDETRDetector(Detector):
    def __init__(self):
        print("加载 RT-DETR 检测模型")
    
    def infer(self, img):
        print("RT-DETR 推理完成")
        return [{"box": [15,25,95,195], "score":0.98}]

# ------------------------------
# 3. 简单工厂:统一创建模型
# ------------------------------
class DetectorFactory:
    @staticmethod
    def create_detector(model_type: str = "yolov8") -> Detector:
        if model_type == "yolov8":
            return YOLOv8Detector()
        elif model_type == "rtdetr":
            return RTDETRDetector()
        else:
            raise ValueError("不支持的模型类型")

# ------------------------------
# 业务使用(前端/主函数)
# ------------------------------
if __name__ == "__main__":
    # 想换模型只改这里,业务代码完全不动
    detector = DetectorFactory.create_detector("yolov8") 
    img = cv2.imread("test.jpg")
    result = detector.infer(img)
    print(result)

你的收益

  • 换模型只改一个字符串,不用改推理、后处理、绘图逻辑。
  • 模型加载细节全藏在工厂里,业务层干净。

场景2:工厂方法 → 扩展新后处理算法(符合开闭原则)

适用 :你要加新的NMS、新的后处理方式,不修改原有代码,直接新增类+工厂。

比如:普通NMS、DIoU-NMS、医疗影像专用后处理。

python 复制代码
# ------------------------------
# 1. 后处理接口
# ------------------------------
class PostProcess:
    def process(self, preds):
        raise NotImplementedError

# ------------------------------
# 2. 具体后处理
# ------------------------------
class NMSPostProcess(PostProcess):
    def process(self, preds):
        print("执行普通NMS")
        return preds

class DIoUNMSPostProcess(PostProcess):
    def process(self, preds):
        print("执行DIoU-NMS")
        return preds

# ------------------------------
# 3. 工厂方法:一个处理对应一个工厂
# ------------------------------
class PostProcessFactory:
    def create(self) -> PostProcess:
        raise NotImplementedError

class NMSFactory(PostProcessFactory):
    def create(self):
        return NMSPostProcess()

class DIoUFactory(PostProcessFactory):
    def create(self):
        return DIoUNMSPostProcess()

# ------------------------------
# 使用
# ------------------------------
factory = DIoUFactory()
post = factory.create()
post.process([])

你的收益

  • 以后加Soft NMS、后处理滤波,只新增类,不碰旧代码。
  • 多人协作不会改乱核心逻辑。

场景3:抽象工厂 → 整套CV流水线(预处理+模型+后处理)

最贴合你医疗AI/尿液检测/舌诊项目

一个工厂生产一整套流程
预处理 → 模型推理 → 后处理

不同任务(检测/分割)、不同硬件(TensorRT/ONNX)用不同工厂。

python 复制代码
# ------------------------------
# 产品族:预处理、推理、后处理
# ------------------------------
class PreProcess:
    def run(self, img): pass
class Infer:
    def run(self, img): pass
class PostProcess:
    def run(self, pred): pass

# ------------------------------
# YOLOv8 + TensorRT 整套流水线
# ------------------------------
class TRTYoloPreProcess(PreProcess):
    def run(self, img): print("TRT-YOLO 预处理:letterbox+归一化")
class TRTYoloInfer(Infer):
    def run(self, img): print("TensorRT 推理")
class TRTYoloPostProcess(PostProcess):
    def run(self, pred): print("TRT-YOLO NMS后处理")

# ------------------------------
# 抽象工厂
# ------------------------------
class CVFactory:
    def create_pre(self) -> PreProcess: pass
    def create_infer(self) -> Infer: pass
    def create_post(self) -> PostProcess: pass

# ------------------------------
# 具体工厂:YOLOv8-TensorRT 工厂
# ------------------------------
class TRTYoloFactory(CVFactory):
    def create_pre(self): return TRTYoloPreProcess()
    def create_infer(self): return TRTYoloInfer()
    def create_post(self): return TRTYoloPostProcess()

# ------------------------------
# 业务调用:一套流程直接跑
# ------------------------------
factory = TRTYoloFactory()
pre = factory.create_pre()
infer = factory.create_infer()
post = factory.create_post()

img = None
pre.run(img)
feat = infer.run(img)
post.run(feat)

你的收益

  • 切换部署平台(TensorRT ↔ ONNX ↔ RKNN),只换工厂。
  • 检测、分割、医疗影像任务,流水线高度统一。
  • 项目工程化极强,适合做成SDK给别人调用。

三、作为图像算法工程师,工厂模式的核心价值

  1. 实验效率爆炸
    对比YOLOv8/RT-DETR/自定义模型,不用删改代码,直接传参切换。
  2. 工程落地不混乱
    模型加载、推理、预处理解耦,不会出现几千行的infer.py
  3. 跨硬件部署零成本
    TensorRT/ONNX/RKNN 一套代码适配,业务层完全无感。
  4. 多人协作不冲突
    算法同学加模型,工程同学改流程,互不干扰。
  5. 医疗/工业视觉项目必备
    多任务、多模型、多设备,必须用工厂做模块化管理。

四、一句话总结(CV视角)

  • 简单工厂:日常快速切换模型,用得最多。
  • 工厂方法:扩展新算法/后处理,保证代码可维护。
  • 抽象工厂:封装整套CV流水线,做工程化SDK。
相关推荐
好家伙VCC1 小时前
**基于RISC-V架构的嵌入式系统开发:从零开始构建高效低功耗应用**在当前物联网(IoT)和边缘计
java·python·物联网·架构·risc-v
大佬王2 小时前
WebSocket 连接池生产级实现:实时行情高可用与负载均衡
python·架构
ronindong2 小时前
Cursor 插件分享 | md-couture:一键将 Markdown 转换成带精美样式的 HTML
人工智能·python·ai编程
智慧地球(AI·Earth)2 小时前
规则引擎实战:Python中re库和pyknow库规则引擎实战教程
开发语言·python·程序人生
是小蟹呀^2 小时前
【总结】LangChain中的中间件Middleware
python·中间件·langchain·agent
qq_342295822 小时前
如何为容器内多个列表实现统一滚动条.txt
jvm·数据库·python
FreakStudio3 小时前
MicroPython对接大模型:uopenai + 火山方舟实现文字聊天和图片理解
python·单片机·ai·嵌入式·面向对象·电子diy
Kimliao1663 小时前
TFT-LCD液晶显示模组常见驱动电压的作用
python
qq_206901393 小时前
CSS如何引入自适应图标_利用svg外链配合css控制颜色
jvm·数据库·python