设计模式-三种工厂模式精讲(简单工厂、工厂方法、抽象方法)
如下是本文目录1. 为什么需要工厂模式1.1 使用工厂模式要解决的核心痛点1.2 典型使用场景1.3 不适合工厂模式的场景2. 工厂模式三大核心体系与实现方式2.1 简单工厂模式静态工厂·入门首选2.1.1 核心特点2.1.2 实战案例支付方式创建2.1.3 优缺点与适用场景2.2 工厂方法模式标准核心·高扩展首选2.2.1 核心特点2.2.2 实战案例支付场景优化2.2.3 优缺点与适用场景2.3 抽象工厂模式高阶工程·系列产品首选2.3.1 核心特点2.3.2 实战案例支付退款系列产品族2.3.3 优缺点与适用场景3. 三大工厂模式全方位对比4. 工厂模式核心痛点与工程解决方案4.1 工厂类/产品类过多类爆炸4.2 简单工厂违反开闭原则4.3 对象重复创建、性能冗余4.4 未知产品类型容错问题5. 高频面试相似模式核心区分6. 工厂模式在主流框架中的落地面试高频6.1 Spring Framework6.2 Hibernate6.3 JPA6.4 Apache 开源组件6.5 客户端如何简单辨认具体的工厂模式7. 核心总结1. 为什么需要工厂模式工厂模式是创建型设计模式核心目标封装对象的创建逻辑统一对象生产入口将对象创建与对象使用彻底解耦。使用者无需关心对象的创建细节、依赖关系、初始化规则只需通过统一工厂入口获取所需对象大幅降低代码耦合度。换句话讲工厂模式就是把所有对象new创建、参数初始化、依赖装配、条件创建的重复代码抽离到统一工厂类业务代码只负责使用对象不负责创建对象彻底实现「对象创建与业务使用分离」。1.1 使用工厂模式要解决的核心痛点a.对象创建逻辑分散冗余业务多处重复new同类对象初始化参数、创建逻辑重复编写修改时需要全量改动维护成本极高b.创建逻辑与业务逻辑强耦合业务代码既要处理核心业务流程又要维护对象创建规则代码职责混乱可读性、可维护性极差c.复杂创建逻辑污染主流程部分对象存在多参数初始化、条件分支创建、依赖嵌套等复杂逻辑直接写在业务代码中会导致主流程臃肿、逻辑混乱d.新增对象违反开闭原则硬编码创建对象时新增业务对象必须修改核心业务代码破坏代码扩展性迭代风险高e.无法统一管控对象对象零散创建无法实现全局缓存、单例管控、统一初始化、配置适配项目缺乏统一规范。1.2 典型使用场景a. 对象创建逻辑复杂、存在多条件分支创建的业务场景b. 系统需要批量创建相似、同系列、同品类对象的场景c. 对象创建规则动态变更、后续需要持续扩展产品类型的迭代场景d. 需要统一管控对象实例缓存、单例、统一初始化、全局配置的场景e. 客户端完全不需要感知对象创建细节仅需使用对象的业务场景。1.3 不适合工厂模式的场景a.对象创建逻辑极简无参数、无判断、固定 new 对象无需封装工厂强行封装属于过度设计b.产品类型永久固定终身仅有单一对象、无任何新增扩展需求工厂模式无实际意义c.临时一次性对象仅单次业务使用、无需复用、无需统一管理的临时对象d.高频销毁重建的轻量化对象无统一管控价值、生命周期极短的微小对象。2. 工厂模式三大核心体系与实现方式工厂模式是创建型模式的核心体系整体分为简单工厂、工厂方法、抽象工厂三个层级三者逐级优化、逐级复杂开闭原则落地程度、代码扩展性、业务适配性逐级提升分别适配不同复杂度的业务场景。核心演进逻辑从「单一工厂包办所有创建」到「一厂一品单一职责」再到「一厂一族批量创建系列产品」完美适配从简单业务到复杂组件化业务的全场景。2.1 简单工厂模式静态工厂·入门首选2.1.1 核心特点简单工厂是工厂模式的最简实现不属于GOF标准设计模式但工程使用最广泛。核心是通过一个统一的工厂类根据传入的类型参数通过条件判断创建不同的产品对象收拢所有产品的创建逻辑统一对象生产入口。核心角色- 抽象产品定义同品类所有产品的统一公共接口/抽象方法规范产品行为- 具体产品实现抽象产品接口完成具体产品的专属业务逻辑- 工厂类唯一创建入口提供静态创建方法根据类型参数匹配并生产对应产品。2.1.2 实战案例支付方式创建// 1. 抽象产品支付统一接口规范所有支付方式行为 public interface Pay { // 统一支付执行方法 void pay(BigDecimal amount); } // 2. 具体产品微信支付 public class WechatPay implements Pay { Override public void pay(BigDecimal amount) { System.out.println(微信支付成功支付金额 amount); } } // 2. 具体产品支付宝支付 public class AliPay implements Pay { Override public void pay(BigDecimal amount) { System.out.println(支付宝支付成功支付金额 amount); } } // 2. 具体产品银行卡支付 public class BankPay implements Pay { Override public void pay(BigDecimal amount) { System.out.println(银行卡支付成功支付金额 amount); } } // 3. 简单工厂统一支付生产工厂 public class PaySimpleFactory { // 静态创建方法客户端直接调用无需实例化工厂 public static Pay createPay(String payType) { if (wechat.equals(payType)) { return new WechatPay(); } else if (ali.equals(payType)) { return new AliPay(); } else if (bank.equals(payType)) { return new BankPay(); } else { throw new IllegalArgumentException(不支持的支付方式); } } } // 测试调用 public class SimpleFactoryTest { public static void main(String[] args) { // 客户端无需手动new具体支付对象完全由工厂创建 Pay wechatPay PaySimpleFactory.createPay(wechat); wechatPay.pay(new BigDecimal(199.9)); Pay aliPay PaySimpleFactory.createPay(ali); aliPay.pay(new BigDecimal(299.9)); } }2.1.3 优缺点与适用场景优点代码极简、上手成本低统一收拢对象创建逻辑彻底解放客户端new操作减少代码冗余统一对象创建规范。缺点违反开闭原则新增产品必须修改工厂类的if/else分支逻辑工厂类职责过重产品数量过多时会导致工厂代码极度臃肿、维护困难。适用场景产品类型固定、迭代频率低、极少新增类型、产品数量少的简单对象创建场景是小型业务、快速开发的首选。2.2 工厂方法模式标准核心·高扩展首选2.2.1 核心特点工厂方法模式是针对简单工厂的核心缺陷优化而来是GOF标准设计模式。核心思想工厂抽象、产品抽象、一一对应、单一职责。为每一个具体产品单独创建专属工厂通过抽象工厂定义统一创建规范具体工厂仅负责生产对应单一产品。新增产品时只需新增对应产品类和工厂类无需修改原有代码完美符合开闭原则彻底解决简单工厂扩展性差的问题。核心角色-抽象产品统一所有产品的业务规范-具体产品实现抽象产品完成专属业务逻辑-抽象工厂定义统一的产品创建方法规范所有工厂行为-具体工厂每个工厂仅对应一款产品只负责该产品的创建与初始化严格单一职责。2.2.2 实战案例支付场景优化// 1. 抽象产品与简单工厂一致统一支付规范 public interface Pay { void pay(BigDecimal amount); } // 具体产品微信支付 public class WechatPay implements Pay { Override public void pay(BigDecimal amount) { System.out.println(微信支付成功支付金额 amount); } } // 具体产品支付宝支付 public class AliPay implements Pay { Override public void pay(BigDecimal amount) { System.out.println(支付宝支付成功支付金额 amount); } } // 2. 抽象工厂统一工厂创建规范 public interface PayFactory { // 统一产品创建方法所有工厂必须实现 Pay createPay(); } // 3. 具体工厂微信支付工厂仅生产微信支付产品 public class WechatPayFactory implements PayFactory { Override public Pay createPay() { // 可封装微信支付专属的复杂初始化逻辑 return new WechatPay(); } } // 具体工厂支付宝支付工厂仅生产支付宝支付产品 public class AliPayFactory implements PayFactory { Override public Pay createPay() { return new AliPay(); } } // 测试调用 public class FactoryMethodTest { public static void main(String[] args) { // 通过专属工厂获取对应产品完全解耦 PayFactory wechatFactory new WechatPayFactory(); Pay wechatPay wechatFactory.createPay(); wechatPay.pay(new BigDecimal(99.9)); PayFactory aliFactory new AliPayFactory(); Pay aliPay aliFactory.createPay(); aliPay.pay(new BigDecimal(169.9)); } }2.2.3 优缺点与适用场景优点完全符合开闭原则、单一职责原则工厂与产品一一对应扩展灵活新增产品零侵入原有代码迭代风险低每个工厂逻辑单一便于维护、测试。缺点每新增一款产品必须新增对应的工厂类会产生类爆炸问题小幅增加项目代码量和类文件数量。适用场景产品类型多、需要频繁横向扩展、对代码扩展性和稳定性要求高的企业级业务场景。2.3 抽象工厂模式高阶工程·系列产品首选2.3.1 核心特点工厂方法模式仅能生产单一品类、单一等级的产品无法适配多组件、多关联的系列化产品场景。抽象工厂模式作为工厂体系的高阶实现核心用于解决关联系列产品的批量创建问题。核心核心概念产品等级、产品族-产品等级同一功能、不同实现的单品称为一个产品等级。如微信支付、支付宝支付都属于支付产品等级-产品族同一品牌/同一体系下的所有关联配套产品如微信支付、微信退款、微信对账属于微信产品族。通俗总结工厂方法是「一厂造一品」抽象工厂是「一厂造一整套系列产品」。核心角色抽象工厂定义系列产品创建规范、具体工厂生产完整产品族、抽象系列产品多等级产品规范、具体系列产品。2.3.2 实战案例支付退款系列产品族// 产品等级1支付接口系列产品1 public interface Pay { void pay(BigDecimal amount); } public class WechatPay implements Pay { Override public void pay(BigDecimal amount) { System.out.println(微信支付 amount); } } public class AliPay implements Pay { Override public void pay(BigDecimal amount) { System.out.println(支付宝支付 amount); } } // 产品等级2退款接口系列产品2 public interface Refund { void refund(BigDecimal amount); } public class WechatRefund implements Refund { Override public void refund(BigDecimal amount) { System.out.println(微信退款 amount); } } public class AliRefund implements Refund { Override public void refund(BigDecimal amount) { System.out.println(支付宝退款 amount); } } // 抽象工厂定义整套产品族创建规范 public interface PaymentFactory { // 创建支付产品 Pay createPay(); // 创建退款产品 Refund createRefund(); } // 具体工厂微信产品族工厂生产微信全套产品 public class WechatPaymentFactory implements PaymentFactory { Override public Pay createPay() { return new WechatPay(); } Override public Refund createRefund() { return new WechatRefund(); } } // 具体工厂支付宝产品族工厂生产支付宝全套产品 public class AliPaymentFactory implements PaymentFactory { Override public Pay createPay() { return new AliPay(); } Override public Refund createRefund() { return new AliRefund(); } } // 测试调用 public class AbstractFactoryTest { public static void main(String[] args) { // 一次性获取微信全套系列产品 PaymentFactory wechatFactory new WechatPaymentFactory(); wechatFactory.createPay().pay(new BigDecimal(200)); wechatFactory.createRefund().refund(new BigDecimal(50)); // 一次性获取支付宝全套系列产品 PaymentFactory aliFactory new AliPaymentFactory(); aliFactory.createPay().pay(new BigDecimal(300)); } }2.3.3 优缺点与适用场景优点完美适配系列化、配套化产品批量创建保证同一产品族的产品统一匹配、无错乱产品族扩展灵活代码高度解耦统一管控系列产品创建逻辑。缺点新增产品等级时需要修改抽象工厂及所有具体工厂违反开闭原则整体结构复杂、学习和维护成本高过度设计风险高。适用场景存在多组关联配套产品的组件化业务典型场景操作系统UI组件按钮/弹窗/输入框、支付体系支付/退款/对账、文件操作读写/加密/解析。3. 三大工厂模式全方位对比模式核心能力开闭原则类爆炸复杂度适用场景简单工厂单一工厂创建多类单品统一入口不满足新增改工厂无极低产品固定、极少扩展、简单创建场景工厂方法一厂一品支持单品横向无限扩展完全满足有中等单品频繁扩展、高扩展性业务抽象工厂一厂一族批量创建系列关联产品产品族满足产品等级不满足较多高多系列配套产品、组件化业务4. 工厂模式核心痛点与工程解决方案4.1 工厂类/产品类过多类爆炸问题描述工厂方法、抽象工厂模式下新增产品必须新增对应工厂类长期迭代会导致项目类文件泛滥结构臃肿。解决方案1.简单固定产品场景优先使用简单工厂无需拆分多个工厂类收拢代码2.规范化分包管理统一建立factory工厂、product产品、impl实现类分包规整项目结构3.Spring 工程优化将工厂、产品交由容器托管利用单例特性减少冗余实例简化配置。4.2 简单工厂违反开闭原则问题描述简单工厂依赖硬编码 if/else 分支新增产品必须修改工厂核心代码存在迭代风险。解决方案1. 需频繁扩展的场景直接升级为工厂方法模式2.折中优化通过配置文件、枚举映射产品类型消除硬编码分支3. 利用反射机制动态创建对象无需修改工厂代码即可新增产品。4.3 对象重复创建、性能冗余问题描述传统工厂每次调用都new新对象高频调用场景下会产生大量临时对象造成GC压力。解决方案1.无状态产品对象通过静态Map缓存实例全局复用避免重复创建2.Spring场景利用容器默认单例特性自动复用产品实例3.有状态对象按需创建结合对象池优化性能。4.4 未知产品类型容错问题问题描述传入无效产品类型时工厂抛出原生异常提示不友好程序健壮性差。解决方案1.增加参数校验、非空判断提前拦截无效参数2.自定义业务异常替换原生报错统一异常提示3. 设置默认兜底产品避免空对象返回。5. 高频面试相似模式核心区分工厂模式 vs 策略模式-工厂模式关注对象创建核心是解决「对象怎么来」的问题统一对象生产、解耦创建逻辑-策略模式关注算法行为核心是解决「行为怎么执行」的问题支持算法动态替换、解耦业务分支。工厂模式 vs 单例模式-工厂模式专注对象创建管控可生产多实例、多类型对象-单例模式专注对象实例唯一性保证全局仅有一个实例。6. 工厂模式在主流框架中的落地面试高频6.1 Spring FrameworkSpring核心容器就是典型的工厂模式落地BeanFactorySpring顶层工厂接口定义Bean统一创建、获取规范ApplicationContextBeanFactory子接口拓展企业级能力是具体的高级工厂实现Spring通过工厂模式统一创建、托管所有Bean业务代码无需手动创建对象。6.2 HibernateSessionFactory工厂接口负责创建Session数据库会话对象屏蔽连接创建细节统一数据库操作实例生产。6.3 JPAEntityManagerFactory工厂类统一创建EntityManager实体管理器实现持久化对象的统一创建与管理。6.4 Apache 开源组件Apache Commons大量工具类使用静态工厂方法创建实例Apache POI根据Excel版本不同通过工厂创建HSSFWorkbook / XSSFWorkbook不同实例。框架组件对应工厂模式核心依据Spring BeanFactory/ApplicationContext工厂方法模式内含简单工厂逻辑存在抽象工厂 多套具体上下文工厂单一产品 BeanHibernate SessionFactory工厂方法模式抽象工厂仅生产 Session 单一产品JPA EntityManagerFactory工厂方法模式多厂商具体工厂只生产 EntityManagerApache Commons 静态工具简单工厂静态工厂静态方法统一创建无分层工厂Apache POI WorkbookFactory简单工厂静态工厂静态方法分支判断生成不同 Workbook6.5 客户端如何简单辨认具体的工厂模式简单工厂模式客户端一直使用同一个途径统一工厂类创建对象。工厂方法模式客户端通过不同的需求使用不同的具体工厂实现类创建对象。抽象工厂模式客户端通过不同的需求使用不同的具体工厂实现类创建对象还可以获取到该产品族具体工厂实现类下的不同产品。7. 核心总结工厂模式的核心本质是解耦对象创建与业务使用统一对象生产入口拥抱开闭原则彻底解决代码冗余、耦合严重、扩展性差的问题三种模式适配不同业务场景按需选择即可无需过度设计1.简单工厂极简高效适合产品固定、无需频繁扩展的简单场景日常开发最常用2.工厂方法标准高扩展适合单品频繁迭代、对代码规范和扩展性有要求的企业级场景3.抽象工厂高阶组件化仅适合多系列、多配套的关联产品场景杜绝滥用4.核心原则简单场景不强行封装复杂场景按需升级以「解耦、可维护、可扩展」为核心目标避免过度设计。