Java 23 种设计模式从踩坑到精通 | 番外工厂方法 vs 抽象工厂 —— 从单产品到产品族架构如何演进摘要工厂方法和抽象工厂都是创建型模式都用于解耦对象的创建与使用。但它们的核心区别在于粒度——工厂方法解决单一产品类型的横向扩展抽象工厂解决产品族的纵向创建。本文从支付渠道对接的真实场景出发沿着“简单工厂 → 工厂方法 → 抽象工厂”的演进路线结合代码对比、UML 分析和 Spring、MyBatis 源码帮你彻底搞懂这对“创建型兄弟”的选型边界。️本文阅读地图3 分钟速览为什么支付收款必须成套创建简单工厂 → 工厂方法 → 抽象工厂一张图看懂演进UML 对比单一产品 vs 产品族继承 vs 组合手写代码对比从一坨 if-else 到可插拔的工厂架构SpringBeanFactoryvsFactoryBeanMyBatisSqlSessionFactory如何体现面试必问“工厂方法和抽象工厂怎么选抽象工厂完全符合开闭原则吗”《Java 23 种设计模式从踩坑到精通》开篇系列介绍与目录 当前番外 · 工厂方法 vs 抽象工厂 返回系列总目录文章目录Java 23 种设计模式从踩坑到精通 | 番外工厂方法 vs 抽象工厂 —— 从单产品到产品族架构如何演进1. 从“支付渠道对接”的架构演进说起2. UML 对比单一产品 vs 产品族2.1 工厂方法 UML一个工厂一个产品2.2 抽象工厂 UML一个工厂一族产品3. 三大核心区别4. 代码演进从简单工厂到抽象工厂4.1 简单工厂最简陋4.2 工厂方法单产品扩展4.3 抽象工厂产品族成套创建5. 框架中的体现5.1 SpringBeanFactory vs FactoryBean5.2 MyBatisSqlSessionFactory6. 面试必问 追问连环炮 《Java 23 种设计模式从踩坑到精通》快速导航1. 从“支付渠道对接”的架构演进说起假设你正在开发一个电商平台的支付模块最初只需要支持支付宝支付。你写了一个简单工厂根据参数创建支付对象// 简单工厂一个工厂创建多种产品publicclassPayFactory{publicstaticIPaycreate(Stringchannel){if(alipay.equals(channel))returnnewAliPay();if(wechat.equals(channel))returnnewWxPay();thrownewIllegalArgumentException(不支持的支付渠道);}}后来业务发展你发现支付和收款必须成套创建——用户用支付宝付了款就必须用支付宝的收款接口去对账否则出现“串渠道”的生产事故。这时候简单工厂的弊端暴露无遗它无法保证“支付对象”和“收款对象”来自同一个渠道。于是架构演进开始先用工厂方法让每个渠道有独立的工厂再用抽象工厂为每个渠道提供一整套产品族支付 收款。2. UML 对比单一产品 vs 产品族2.1 工厂方法 UML一个工厂一个产品2.2 抽象工厂 UML一个工厂一族产品UML 的关键差异工厂方法的抽象工厂接口只有一个createProduct()方法抽象工厂有多个创建方法createPay()createCollect()工厂方法的一个具体工厂对应一个具体产品抽象工厂的一个具体工厂对应一个产品族一组关联产品。3. 三大核心区别对比维度工厂方法抽象工厂意图定义创建对象的接口让子类决定实例化哪个类创建一系列相关或相互依赖的对象产品族工厂职责一个工厂只创建一种产品一个工厂创建一族产品扩展方向新增产品只需新加工厂类完全符合开闭原则新增产品族符合开闭原则但新增产品类型如新增退款功能需要修改抽象工厂接口和所有具体工厂违反开闭原则典型应用SpringFactoryBean、简单支付扩展MyBatisSqlSessionFactory、支付收款成套创建简单记忆工厂方法是“一个产品一条生产线”抽象工厂是“一族产品一个集团”。工厂方法加产品 加一条线抽象工厂加产品类型 整个集团都要改。4. 代码演进从简单工厂到抽象工厂4.1 简单工厂最简陋// 简单工厂一个工厂根据参数返回不同产品publicclassSimplePayFactory{publicstaticIPaycreatePay(Stringchannel){switch(channel){casealipay:returnnewAliPay();casewechat:returnnewWxPay();default:thrownewIllegalArgumentException(不支持的渠道);}}}⚠️ 问题新增渠道需修改switch违反开闭原则无法保证支付和收款配套。4.2 工厂方法单产品扩展// 工厂方法每个渠道一个工厂只创建支付对象publicinterfacePayFactory{IPaycreatePay();}publicclassAliPayFactoryimplementsPayFactory{OverridepublicIPaycreatePay(){returnnewAliPay();}}publicclassWxPayFactoryimplementsPayFactory{OverridepublicIPaycreatePay(){returnnewWxPay();}}✅ 优点新增渠道只需加新工厂类。⚠️ 问题收款对象需要另外创建无法保证支付和收款来自同一渠道。4.3 抽象工厂产品族成套创建// 抽象工厂一个工厂同时创建支付和收款publicabstractclassPaymentFactory{publicabstractIPaycreatePay();publicabstractICollectcreateCollect();}publicclassAliPaymentFactoryextendsPaymentFactory{OverridepublicIPaycreatePay(){returnnewAliPay();}OverridepublicICollectcreateCollect(){returnnewAliCollect();}}publicclassWxPaymentFactoryextendsPaymentFactory{OverridepublicIPaycreatePay(){returnnewWxPay();}OverridepublicICollectcreateCollect(){returnnewWxCollect();}}✅ 优点支付和收款强制配套杜绝“串渠道”切换渠道只需替换工厂实例。⚠️ 缺点如果需要新增“退款”产品必须修改PaymentFactory抽象类和所有具体工厂。演进总结简单工厂 工厂方法 抽象工厂 ──────→ ──────→ ──────→ 一个工厂多种产品 每个产品一个工厂 一个工厂一族产品 集中但违反OCP 扩展性强 保证产品族一致 支付场景起步 支付扩展 支付收款配套5. 框架中的体现5.1 SpringBeanFactoryvsFactoryBeanBeanFactoryIoC 容器的核心接口负责管理和创建所有 Bean。它不关心具体产品可以看作一个超级“抽象工厂”。FactoryBeanT一个专门用于创建复杂对象的工厂 Bean每次getObject()返回一个特定类型的产品。这是典型的工厂方法模式——每个FactoryBean只创建一种产品。// FactoryBean工厂方法模式ComponentpublicclassMyServiceFactoryBeanimplementsFactoryBeanMyService{OverridepublicMyServicegetObject(){returnnewMyService();}// 只创建一种产品OverridepublicClass?getObjectType(){returnMyService.class;}}5.2 MyBatisSqlSessionFactorySqlSessionFactory是典型的抽象工厂模式——它创建SqlSession以及与当前数据库环境关联的Configuration、Transaction等对象构成一个完整的产品族。切换数据库环境只需替换SqlSessionFactory的实现。6. 面试必问 追问连环炮基础必问工厂方法和抽象工厂的区别 工厂方法解决单一产品扩展抽象工厂解决产品族创建。工厂方法的抽象工厂只有一个create()方法抽象工厂有多个。抽象工厂完全符合开闭原则吗 不完全。新增产品族新增一个支付渠道符合 OCP但新增产品类型如新增退款功能需要修改抽象工厂接口和所有具体工厂违反 OCP。这是面试中经常考察的点。面试官追问“什么时候该用抽象工厂而不是工厂方法” 当系统需要创建的对象之间存在“成套”或“风格统一”的强关联时。如支付收款必须来自同一渠道、跨平台 UI 的按钮文本框必须风格一致。“BeanFactory和FactoryBean分别是什么模式”BeanFactory是抽象工厂模式管理所有 Bean 的容器FactoryBean是工厂方法模式生产特定复杂对象的工厂。“简单工厂、工厂方法、抽象工厂如何演进” 产品种类少且固定 → 简单工厂产品种类多、频繁新增 → 工厂方法产品成族出现、需整体切换 → 抽象工厂。三者是一个“从集中到分散、从单产品到产品族”的演进过程。恭喜如果你能立刻画出工厂方法和抽象工厂的 UML 对比图并说出“新增产品类型时抽象工厂违反 OCP”你已经掌握了创建型模式最核心的选型逻辑。延伸阅读本文是工厂方法模式与抽象工厂模式的深度对比。如果你想先了解每种模式的完整原理、UML、代码实现和面试题可以先阅读正篇——工厂模式简单工厂→工厂方法→抽象工厂全演进 和 抽象工厂模式产品族创建如何避免“一锅粥”再回来看这篇对比效果更佳。 《Java 23 种设计模式从踩坑到精通》快速导航开篇系列介绍与目录当前番外 · 工厂方法 vs 抽象工厂 —— 从单产品到产品族架构如何演进你在这里 延伸阅读工厂模式正篇 抽象工厂模式正篇创建型模式汇总结构型模式汇总行为型模式汇总 关注《Java 23 种设计模式从踩坑到精通》用 25 篇文章彻底吃透设计模式。福利预告全系列代码及 UML 源码将在完结时统一打包开放点击「关注」「收藏」第一时间获取。 除了设计模式我也在深挖智能物流实战WMS、托盘调度、机器学习落地。欢迎点击头像看看专栏 《出版社物流WMS智能调度实战》。技术相通思路可鉴。