news 2026/4/17 23:49:21

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
工厂模式(Factory Pattern)完整详解

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

工厂模式是软件开发中最常用的创建型设计模式,核心思想是将「对象的创建」与「对象的使用」完全解耦
客户端无需关心对象如何实例化、依赖如何组装,只需要通过「工厂」获取目标对象,极大降低代码耦合,同时满足开闭原则、单一职责原则等设计规范。

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

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

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


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

1. 核心定义

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

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

2. 核心角色

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

3. 代码示例(Python)

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

# 1. 抽象产品:形状接口classShape:defdraw(self):pass# 2. 具体产品:圆形、矩形classCircle(Shape):defdraw(self):print("绘制圆形")classRectangle(Shape):defdraw(self):print("绘制矩形")# 3. 简单工厂类classShapeFactory:@staticmethoddefcreate_shape(shape_type):ifshape_type=="circle":returnCircle()elifshape_type=="rectangle":returnRectangle()else:raiseValueError("不支持的形状类型")# 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)

# 1. 抽象产品classShape:defdraw(self):pass# 2. 具体产品classCircle(Shape):defdraw(self):print("绘制圆形")classRectangle(Shape):defdraw(self):print("绘制矩形")# 3. 抽象工厂classShapeFactory:defcreate_shape(self):pass# 4. 具体工厂:每个产品对应一个工厂classCircleFactory(ShapeFactory):defcreate_shape(self):returnCircle()classRectangleFactory(ShapeFactory):defcreate_shape(self):returnRectangle()# 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)

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

# 1. 抽象产品族:空调、冰箱classAirConditioner:defcool(self):passclassRefrigerator:deffreeze(self):pass# 2. 具体产品族:美的系列、格力系列classMediaAirConditioner(AirConditioner):defcool(self):print("美的空调制冷")classMediaRefrigerator(Refrigerator):deffreeze(self):print("美的冰箱冷冻")classGreeAirConditioner(AirConditioner):defcool(self):print("格力空调制冷")classGreeRefrigerator(Refrigerator):deffreeze(self):print("格力冰箱冷冻")# 3. 抽象工厂:生产整套家电classApplianceFactory:defcreate_air_conditioner(self):passdefcreate_refrigerator(self):pass# 4. 具体工厂classMediaFactory(ApplianceFactory):defcreate_air_conditioner(self):returnMediaAirConditioner()defcreate_refrigerator(self):returnMediaRefrigerator()classGreeFactory(ApplianceFactory):defcreate_air_conditioner(self):returnGreeAirConditioner()defcreate_refrigerator(self):returnGreeRefrigerator()# 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()

核心思路

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

importcv2importnumpyasnp# ------------------------------# 1. 抽象产品:模型推理基类# ------------------------------classDetector:definfer(self,img:np.ndarray)->list:"""模型推理接口"""raiseNotImplementedError# ------------------------------# 2. 具体产品:不同检测模型# ------------------------------classYOLOv8Detector(Detector):def__init__(self):# 加载YOLOv8 onnx/trt模型print("加载 YOLOv8 检测模型")definfer(self,img):print("YOLOv8 推理完成")return[{"box":[10,20,100,200],"score":0.95}]classRTDETRDetector(Detector):def__init__(self):print("加载 RT-DETR 检测模型")definfer(self,img):print("RT-DETR 推理完成")return[{"box":[15,25,95,195],"score":0.98}]# ------------------------------# 3. 简单工厂:统一创建模型# ------------------------------classDetectorFactory:@staticmethoddefcreate_detector(model_type:str="yolov8")->Detector:ifmodel_type=="yolov8":returnYOLOv8Detector()elifmodel_type=="rtdetr":returnRTDETRDetector()else:raiseValueError("不支持的模型类型")# ------------------------------# 业务使用(前端/主函数)# ------------------------------if__name__=="__main__":# 想换模型只改这里,业务代码完全不动detector=DetectorFactory.create_detector("yolov8")img=cv2.imread("test.jpg")result=detector.infer(img)print(result)

你的收益

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

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

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

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

# ------------------------------# 1. 后处理接口# ------------------------------classPostProcess:defprocess(self,preds):raiseNotImplementedError# ------------------------------# 2. 具体后处理# ------------------------------classNMSPostProcess(PostProcess):defprocess(self,preds):print("执行普通NMS")returnpredsclassDIoUNMSPostProcess(PostProcess):defprocess(self,preds):print("执行DIoU-NMS")returnpreds# ------------------------------# 3. 工厂方法:一个处理对应一个工厂# ------------------------------classPostProcessFactory:defcreate(self)->PostProcess:raiseNotImplementedErrorclassNMSFactory(PostProcessFactory):defcreate(self):returnNMSPostProcess()classDIoUFactory(PostProcessFactory):defcreate(self):returnDIoUNMSPostProcess()# ------------------------------# 使用# ------------------------------factory=DIoUFactory()post=factory.create()post.process([])

你的收益

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

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

最贴合你医疗AI/尿液检测/舌诊项目
一个工厂生产一整套流程
预处理 → 模型推理 → 后处理

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

# ------------------------------# 产品族:预处理、推理、后处理# ------------------------------classPreProcess:defrun(self,img):passclassInfer:defrun(self,img):passclassPostProcess:defrun(self,pred):pass# ------------------------------# YOLOv8 + TensorRT 整套流水线# ------------------------------classTRTYoloPreProcess(PreProcess):defrun(self,img):print("TRT-YOLO 预处理:letterbox+归一化")classTRTYoloInfer(Infer):defrun(self,img):print("TensorRT 推理")classTRTYoloPostProcess(PostProcess):defrun(self,pred):print("TRT-YOLO NMS后处理")# ------------------------------# 抽象工厂# ------------------------------classCVFactory:defcreate_pre(self)->PreProcess:passdefcreate_infer(self)->Infer:passdefcreate_post(self)->PostProcess:pass# ------------------------------# 具体工厂:YOLOv8-TensorRT 工厂# ------------------------------classTRTYoloFactory(CVFactory):defcreate_pre(self):returnTRTYoloPreProcess()defcreate_infer(self):returnTRTYoloInfer()defcreate_post(self):returnTRTYoloPostProcess()# ------------------------------# 业务调用:一套流程直接跑# ------------------------------factory=TRTYoloFactory()pre=factory.create_pre()infer=factory.create_infer()post=factory.create_post()img=Nonepre.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。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/17 23:48:15

Dynamic-Datasource多模块依赖管理:Bill of Materials终极指南

Dynamic-Datasource多模块依赖管理:Bill of Materials终极指南 【免费下载链接】dynamic-datasource dynamic datasource for springboot 多数据源 动态数据源 主从分离 读写分离 分布式事务 项目地址: https://gitcode.com/gh_mirrors/dy/dynamic-datasource …

作者头像 李华
网站建设 2026/4/17 23:46:44

如何将CornerNet集成到你的项目中:7个实际应用案例

如何将CornerNet集成到你的项目中:7个实际应用案例 【免费下载链接】CornerNet 项目地址: https://gitcode.com/gh_mirrors/co/CornerNet CornerNet是一种创新的目标检测算法,它通过将物体检测视为成对关键点检测问题,实现了高精度的…

作者头像 李华
网站建设 2026/4/17 23:42:12

Rust-doom高级特性:自由飞行相机、天空渲染与光照效果实现

Rust-doom高级特性:自由飞行相机、天空渲染与光照效果实现 【免费下载链接】rust-doom A Doom Renderer written in Rust. 项目地址: https://gitcode.com/gh_mirrors/ru/rust-doom Rust-doom是一款使用Rust语言编写的Doom渲染器,它不仅复刻了经典…

作者头像 李华
网站建设 2026/4/17 23:39:01

mysql如何通过Docker快速搭建_mysql容器化部署实践

连不上MySQL容器需检查:-p端口映射是否显式指定、--network自定义网络下必须用-p而非直连IP;Linux需确认防火墙未拦截3306;root密码须通过MYSQ_ROOT_PASSWORD设置且仅首次初始化生效;init脚本仅在空数据目录时执行;8.0…

作者头像 李华