核心内容摘要
谁在定义“乱女小芳”?撕掉标签,活出生命最野性的秩序
目录前言
什么是工厂方法模式
工厂方法模式的核心结构
抽象产品Product
具体产品Concrete Product
抽象工厂Factory
具体工厂Concrete Factory
Java实战工厂方法模式代码实现
定义抽象产品日志接口
实现具体产品文件日志、控制台日志
定义抽象工厂日志工厂接口
实现具体工厂文件日志工厂、控制台日志工厂
客户端调用使用工厂创建产品运行结果扩展新产品数据库日志
工厂方法模式的应用场景
工厂方法模式的优缺点优点缺点
工厂方法模式与简单工厂模式的区别
七、
总结前言作为Java开发者我们日常编码中总会面临对象创建的场景。
如果直接通过new关键字实例化对象会导致代码耦合度偏高后续需求迭代时修改成本激增。
工厂方法模式作为创建型设计模式的核心成员正是为解决对象创建与使用的解耦问题而生。
本文将从定义、结构、实现、应用场景等维度带你彻底吃透工厂方法模式助力写出更灵活、可维护的Java代码。
什么是工厂方法模式工厂方法模式Factory Method Pattern的核心定义定义一个创建对象的接口抽象工厂让子类决定实例化哪个类具体产品使一个类的实例化延迟到其子类。
简单来说就是“把对象创建的活儿交给子类来做”通过抽象工厂约定创建逻辑由具体工厂负责具体产品的实例化彻底隔绝产品创建与产品使用的直接关联。
它是对“简单工厂模式”的优化升级——简单工厂模式通过一个工厂类集中创建所有产品违背了“开闭原则”新增产品需修改工厂代码而工厂方法模式将工厂抽象化新增产品时只需新增对应具体工厂无需改动原有代码完美契合开闭原则是更具扩展性的创建方案。
工厂方法模式的核心结构工厂方法模式包含4个核心角色各角色职责清晰协同完成对象创建与解耦结合Java场景拆解如下
抽象产品Product定义所有具体产品的公共接口或抽象类规范产品的核心行为。
它是工厂方法模式中产品的“顶层规范”确保所有具体产品都具备统一的功能便于客户端统一调用。
具体产品Concrete Product抽象产品的具体实现类是工厂方法模式最终要创建的对象。
每个具体产品对应一个具体工厂由具体工厂负责其实例化。
抽象工厂Factory定义创建产品的抽象方法该方法返回抽象产品类型不涉及具体产品的创建逻辑。
抽象工厂可以是接口也可以是抽象类其核心职责是约定“如何创建产品”而非“创建哪种产品”。
具体工厂Concrete Factory抽象工厂的实现类重写抽象工厂的创建方法负责实例化具体产品。
每个具体工厂对应一种具体产品新增产品时只需新增对应的具体产品类和具体工厂类即可。
Java实战工厂方法模式代码实现我们以“日志记录器”为例实现工厂方法模式。
需求支持两种日志记录方式文件日志、控制台日志后续可灵活扩展数据库日志等新类型且新增时不修改原有代码。
定义抽象产品日志接口/** * 抽象产品日志记录器接口 * 定义所有日志的公共行为 */ public interface Logger { // 日志记录方法 void log(String message); }
实现具体产品文件日志、控制台日志/** * 具体产品1文件日志记录器 */ public class FileLogger implements Logger { Override public void log(String message) { System.out.println(文件日志 message); } } /** * 具体产品2控制台日志记录器 */ public class ConsoleLogger implements Logger { Override public void log(String message) { System.out.println(控制台日志 message); } }
定义抽象工厂日志工厂接口/** * 抽象工厂日志工厂接口 * 定义创建日志对象的抽象方法 */ public interface LoggerFactory { // 抽象工厂方法返回抽象产品类型 Logger createLogger(); }
实现具体工厂文件日志工厂、控制台日志工厂/** * 具体工厂1文件日志工厂 * 负责创建文件日志对象 */ public class FileLoggerFactory implements LoggerFactory { Override public Logger createLogger() { // 可在此处添加文件日志的初始化逻辑如创建文件、配置路径等 return new FileLogger(); } } /** * 具体工厂2控制台日志工厂 * 负责创建控制台日志对象 */ public class ConsoleLoggerFactory implements LoggerFactory { Override public Logger createLogger() { // 可在此处添加控制台日志的初始化逻辑 return new ConsoleLogger(); } }
客户端调用使用工厂创建产品/** * 客户端使用工厂方法模式创建日志对象 */ public class Client { public static void main(String[] args) { //
创建具体工厂可根据配置动态选择工厂无需硬编码 LoggerFactory factory new ConsoleLoggerFactory(); //
通过工厂创建产品面向抽象产品编程无需关注具体实现 Logger logger factory.createLogger(); //
使用产品功能 logger.log(工厂方法模式实战演示); // 切换为文件日志只需修改具体工厂无需改动其他代码 factory new FileLoggerFactory(); logger factory.createLogger(); logger.log(切换为文件日志记录); } }运行结果控制台日志工厂方法模式实战演示 文件日志切换为文件日志记录扩展新产品数据库日志若需新增数据库日志只需新增具体产品和具体工厂无需修改原有代码完全符合开闭原则// 新增具体产品数据库日志 public class DatabaseLogger implements Logger { Override public void log(String message) { System.out.println(数据库日志 message); } } // 新增具体工厂数据库日志工厂 public class DatabaseLoggerFactory implements LoggerFactory { Override public Logger createLogger() { // 数据库日志初始化逻辑如连接数据库 return new DatabaseLogger(); } } // 客户端调用新增产品无需修改原有代码 LoggerFactory dbFactory new DatabaseLoggerFactory(); Logger dbLogger dbFactory.createLogger(); dbLogger.log(数据库日志记录);
工厂方法模式的应用场景工厂方法模式适合以下Java开发场景核心是解决“对象创建与使用解耦”和“灵活扩展”问题产品类型不确定需灵活扩展如上述日志案例后续可能新增多种日志类型工厂方法可快速适配无需改动原有逻辑。
对象创建逻辑复杂当对象创建需要初始化配置、依赖其他对象、处理异常等复杂逻辑时可将这些逻辑封装在具体工厂中简化客户端代码。
面向抽象编程降低耦合客户端只需面向抽象产品和抽象工厂编程无需关注具体产品的实现细节符合“依赖倒置原则”。
框架中的应用Java主流框架中大量使用工厂方法模式如Spring的BeanFactory抽象工厂通过getBean()方法工厂方法创建Bean实例不同的BeanFactory实现类对应不同的Bean创建逻辑。
工厂方法模式的优缺点优点符合开闭原则新增产品时只需新增具体产品和具体工厂无需修改原有代码扩展性强。
解耦创建与使用将对象创建逻辑封装在工厂中客户端无需关注创建细节只需使用产品。
符合依赖倒置原则依赖抽象而非具体客户端依赖抽象工厂和抽象产品降低代码耦合度。
单一职责原则每个具体工厂只负责创建一种具体产品职责清晰便于维护。
缺点类数量激增每新增一种产品需对应新增一个具体产品类和一个具体工厂类增加系统复杂度。
系统灵活性依赖抽象层抽象工厂和抽象产品的设计需精准若后续需修改抽象层成本较高。
简单场景冗余对于产品类型固定、无需扩展的简单场景使用工厂方法会增加代码冗余不如直接new对象简洁。
工厂方法模式与简单工厂模式的区别很多Java开发者会混淆两者核心区别在于“是否遵循开闭原则”和“工厂的职责范围”对比维度简单工厂模式工厂方法模式工厂数量一个统一的工厂类一个抽象工厂 多个具体工厂开闭原则违背新增产品需修改工厂代码遵循新增产品只需新增工厂和产品职责划分工厂职责过重负责所有产品创建职责拆分每个工厂只负责一种产品扩展性差修改原有代码易引发风险好灵活扩展无侵入式修改
七、
总结工厂方法模式的
核心价值是将对象的“创建权”与“使用权”分离通过抽象层定义规范让子类承担具体创建职责从而实现代码解耦与灵活扩展。
它是Java设计模式中“创建型模式”的基础也是理解抽象工厂模式、建造者模式的前提。
在实际开发中我们无需盲目使用工厂方法模式——对于简单场景直接new对象更高效但对于产品类型多变、创建逻辑复杂的场景工厂方法模式能显著提升代码的可维护性和扩展性尤其在框架开发中如Spring、MyBatis其应用随处可见。
作为Java学者掌握工厂方法模式不仅能写出更优雅的代码更能理解主流框架的设计思想为后续学习更复杂的设计模式打下坚实基础。