工厂方法模式简介及应用场景

工厂方法模式简介及应用场景:☀️☀️☀️

不积跬步无以至千里,不积小流无以成江河。欢迎交流~

1. 工厂方法模式(Factory Method Pattern)核心解读

工厂方法模式是创建型设计模式的核心之一,定义为:

定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。

1.1 通俗理解

把“创建同类对象的不同实现”(比如创建不同品牌的手机:华为、苹果)抽离为独立的“工厂类”,主逻辑(业务代码)只需调用工厂接口获取对象,无需关心对象的具体创建细节。

1.2 核心角色(4个)

角色作用
抽象产品(Product)定义所有具体产品必须实现的接口/抽象类(如手机的 call() 方法)
具体产品(ConcreteProduct)实现抽象产品,封装产品的具体功能(如华为手机、苹果手机)
抽象工厂(Factory)定义创建产品的接口,包含一个创建产品的抽象方法(如 createPhone())
具体工厂(ConcreteFactory)实现抽象工厂的创建方法,负责实例化具体产品(如华为工厂、苹果工厂)

1.3 核心优势

开闭原则:新增产品时,仅需新增“具体产品类”和“具体工厂类”,无需修改原有工厂和业务代码;

解耦创建与使用:业务逻辑只依赖抽象产品和抽象工厂,不依赖具体实现,降低耦合度;

责任单一:工厂类专注于创建产品,业务类专注于使用产品,符合单一职责原则;

扩展性强:可在运行时通过切换具体工厂,动态创建不同的产品实例。

2. 工厂方法模式在Java中的典型示例(手机创建场景)

以“创建不同品牌手机”为例,对比不用工厂方法模式和用工厂方法模式的实现。

2.1 反例:不用工厂方法模式(耦合严重)

Java
复制代码
// 具体产品类 public class HuaweiPhone { public void call() { System.out.println("华为手机打电话"); } } public class IPhone { public void call() { System.out.println("苹果手机打电话"); } } // 业务逻辑直接依赖具体产品,耦合严重 public class PhoneService { // 新增手机品牌需修改此方法,违反开闭原则 public Object createPhone(String brand) { if ("HUAWEI".equals(brand)) { return new HuaweiPhone(); // 直接创建华为手机 } else if ("IPHONE".equals(brand)) { return new IPhone(); // 直接创建苹果手机 } else { throw new IllegalArgumentException("不支持的手机品牌"); } } public void usePhone(String brand) { // 需强制类型转换,代码臃肿 if ("HUAWEI".equals(brand)) { HuaweiPhone phone = (HuaweiPhone) createPhone(brand); phone.call(); } else if ("IPHONE".equals(brand)) { IPhone phone = (IPhone) createPhone(brand); phone.call(); } } } // 调用方 public class Client { public static void main(String[] args) { PhoneService service = new PhoneService(); service.usePhone("HUAWEI"); } }

问题:

新增品牌(如小米)需修改 createPhone() 和 usePhone() 方法,违反开闭原则;

需手动强制类型转换,代码冗余且易出错;

产品创建细节暴露在业务逻辑中,维护成本高。

2.2 正例:用工厂方法模式重构(大厂标准写法)

步骤1:定义抽象产品(手机接口)

Java
复制代码
// 所有手机的统一接口(抽象产品) public interface Phone { void call(); // 核心功能:打电话 }

步骤2:实现具体产品(各品牌手机)

Java
复制代码
// 华为手机(具体产品) public class HuaweiPhone implements Phone { @Override public void call() { System.out.println("【华为手机】发起通话,支持5G高清通话"); // 华为手机专属功能逻辑(如鸿蒙系统适配) } } // 苹果手机(具体产品) public class IPhone implements Phone { @Override public void call() { System.out.println("【苹果手机】发起通话,支持FaceTime联动"); // 苹果手机专属功能逻辑(如iOS生态适配) } }

步骤3:定义抽象工厂(手机工厂接口)

Java
复制代码
// 手机工厂的统一接口(抽象工厂) public interface PhoneFactory { Phone createPhone(); // 创建手机的抽象方法 }

步骤4:实现具体工厂(各品牌手机工厂)

Java
复制代码
// 华为手机工厂(具体工厂) public class HuaweiFactory implements PhoneFactory { @Override public Phone createPhone() { System.out.println("华为工厂:生产华为Mate系列手机"); // 手机创建前的初始化逻辑(如硬件检测、系统预装) return new HuaweiPhone(); } } // 苹果手机工厂(具体工厂) public class IPhoneFactory implements PhoneFactory { @Override public Phone createPhone() { System.out.println("苹果工厂:生产iPhone 16系列手机"); // 手机创建前的初始化逻辑(如iOS激活、隐私设置) return new IPhone(); } }

步骤5:定义环境类(统一调用入口)

Java
复制代码
// 封装工厂的统一调用入口 public class PhoneContext { // 工厂容器:缓存所有手机工厂 private static final Map<String, PhoneFactory> FACTORY_MAP = new HashMap<>(); // 静态初始化工厂 static { FACTORY_MAP.put("HUAWEI", new HuaweiFactory()); FACTORY_MAP.put("IPHONE", new IPhoneFactory()); } // 外部统一调用方法 public Phone createPhone(String brand) { PhoneFactory factory = FACTORY_MAP.get(brand); if (factory == null) { throw new IllegalArgumentException("不支持的手机品牌:" + brand); } return factory.createPhone(); } // 动态添加新工厂 public void addFactory(String brand, PhoneFactory factory) { FACTORY_MAP.put(brand, factory); } }

步骤6:调用方使用(极简)

Java
复制代码
public class Client { public static void main(String[] args) { PhoneContext context = new PhoneContext(); // 创建华为手机 Phone huaweiPhone = context.createPhone("HUAWEI"); huaweiPhone.call(); // 创建苹果手机 Phone iphone = context.createPhone("IPHONE"); iphone.call(); // 新增小米手机(无需修改原有代码) // context.addFactory("XIAOMI", new XiaomiFactory()); // Phone xiaomiPhone = context.createPhone("XIAOMI"); // xiaomiPhone.call(); } }

输出结果:

Plain
复制代码
华为工厂:生产华为Mate系列手机 【华为手机】发起通话,支持5G高清通话 苹果工厂:生产iPhone 16系列手机 【苹果手机】发起通话,支持FaceTime联动

2.3 Spring环境下的进阶写法(大厂实战)

结合注解+自动注入,无需手动维护工厂容器:

Java
复制代码
// 1. 定义工厂注解 @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface PhoneFactoryAnnotation { String value(); // 手机品牌 } // 2. 具体产品交给Spring管理 @Component public class HuaweiPhone implements Phone { /* 实现方法同上 */ } @Component public class IPhone implements Phone { /* 实现方法同上 */ } // 3. 具体工厂添加注解+交给Spring管理 @PhoneFactoryAnnotation("HUAWEI") @Component public class HuaweiFactory implements PhoneFactory { @Autowired private HuaweiPhone huaweiPhone; @Override public Phone createPhone() { System.out.println("华为工厂:生产华为Mate系列手机"); return huaweiPhone; } } @PhoneFactoryAnnotation("IPHONE") @Component public class IPhoneFactory implements PhoneFactory { @Autowired private IPhone iphone; @Override public Phone createPhone() { System.out.println("苹果工厂:生产iPhone 16系列手机"); return iphone; } } // 4. 环境类自动加载工厂 @Component public class PhoneContext { private final Map<String, PhoneFactory> factoryMap; // Spring自动注入所有PhoneFactory类型的Bean public PhoneContext(List<PhoneFactory> factories) { factoryMap = new HashMap<>(); for (PhoneFactory factory : factories) { String brand = factory.getClass().getAnnotation(PhoneFactoryAnnotation.class).value(); factoryMap.put(brand, factory); } } // 创建手机方法(同上) public Phone createPhone(String brand) { PhoneFactory factory = factoryMap.get(brand); if (factory == null) { throw new IllegalArgumentException("不支持的手机品牌:" + brand); } return factory.createPhone(); } } // 5. 业务层调用 @Service public class OrderService { @Autowired private PhoneContext phoneContext; public void deliverPhone(String brand) { // 订单逻辑... Phone phone = phoneContext.createPhone(brand); System.out.println("配送手机:" + phone.getClass().getSimpleName()); phone.call(); } }

3. 工厂方法模式的典型应用场景(大厂高频)

除手机创建场景外,工厂方法模式在大厂项目中的核心应用:

3.1 多产品系列创建

场景:电商平台的商品创建(实物商品、虚拟商品)、物流系统的包裹创建(普通包裹、冷链包裹);

实现:每种商品/包裹对应“具体产品+具体工厂”,业务层通过抽象工厂统一创建。

3.2 算法/接口适配

场景:日志框架(Logback、Log4j 适配)、ORM框架(MyBatis 不同数据源适配);

实现:每种日志/数据源适配方式封装为工厂类,核心逻辑通过抽象工厂调用。

3.3 框架内置的工厂方法模式

大厂常用框架大量使用工厂方法模式:

JDK:Calendar(不同时区的日历实例)、NumberFormat(不同格式的数字格式化);

Java
复制代码
// Calendar的工厂方法应用 List<Integer> list = Arrays.asList(3,1,2); Calendar chinaCalendar = Calendar.getInstance(TimeZone.getTimeZone("Asia/Shanghai")); Calendar usCalendar = Calendar.getInstance(TimeZone.getTimeZone("America/New_York"));

Spring:BeanFactory(Bean创建工厂)、TransactionManager(不同数据源的事务管理器);

MyBatis:SqlSessionFactory(创建SqlSession实例,适配不同环境)。

4. 大厂为什么重视设计模式?

很多新手认为设计模式是“花架子”,但大厂对其重视程度极高,核心原因:

4.1 解决大规模代码的维护性问题

大厂项目代码量可达百万行,人员流动频繁:

无设计模式:代码是“面条式”new对象,新人接手需逐行读代码,改一行崩一片;

有设计模式:代码遵循统一规范(如工厂方法模式的“接口+实现”),新人快速理解,维护成本降低80%。

4.2 支撑高扩展的业务需求

大厂业务迭代极快(如电商每年新增N种商品类型):

无设计模式:新增功能需修改核心代码,风险高;

有设计模式:新增产品仅需加新类,符合“开闭原则”,上线风险几乎为0。

4.3 实现代码复用+标准化

大厂强调“不重复造轮子”:

工厂方法模式将对象创建逻辑封装为独立类,可在多模块复用;

设计模式是“程序员的通用语言”,说“这里用工厂方法模式”,团队全员理解代码结构,沟通成本降低。

4.4 适配高并发/高可用架构

工厂方法模式的“解耦”特性是高并发架构的基础:

商品创建场景:可按商品类型路由到不同工厂/服务器,实现分流;

数据库连接场景:可按业务模块切换不同连接池工厂,提升性能。

5. 总结

工厂方法模式核心:封装对象创建逻辑为独立工厂,解耦“创建逻辑”与“使用逻辑”;

典型应用:多产品创建、框架扩展、数据源适配等需动态创建对象的场景;

大厂价值:维护性(易读易改)、扩展性(新增产品不碰旧代码)、复用性(工厂类可复用);

避坑点:若仅创建单一产品且永不扩展,无需使用(避免过度设计);复杂多产品族场景,可升级为“抽象工厂模式”。

(注:文档部分内容可能由 AI 生成)

0个评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
她和夏天一样热
作者分享
策略模式简介及应用场景
5
Spring 源码入门篇
4
入职dayone 刚开始还庆幸这家还好是纯springboot那一套框架开发, 但是进来发现整个开发部就四个人,而且目前这个项目完全是由实习生自己开发的,而且是口头给需求,感觉有点小压力, 毕竟之前没实习过,基本没人带,现在就只能靠另外一个实习的哥们帮忙带一下(他在里面干了三四个月好像也快离开了) 而且今天给了一个小需求,然后要我们自己设计新的表😂 目前想法就是先顶住压力干三个月 后面再找找机会 或者等明年春招,这个思路可以嘛? 还有 问一下已经有过实习经历的友友,有没有建议给到我刚入职的萌新, 像给我一个需求 ,我是先去捋一下思路,需要设计表,哪些字段,还有返回给前端什么数据这些 ,是不是得先想好啊, 项目负责人都没告诉我,就是直接口头给需求 然后我们开发就行😭 现在脑子懵,希望有经验的友友给点建议,平时拿到一个需求是怎么开发的呢
3
用宝塔面板部署的项目,现在报连接不上redis 是什么原因呢?我本身项目代码是没问题的 在本地能正常连接,但是怎么连不上宝塔上面下的reids呢?之前还可以 然后后面项目线上报错我就重新删了再搞 结果就报连接不是redis了,配置密码也没问题呀。有大佬有遇到这种问题嘛,求助!
2
#云图库扩展点 #AI上传优化为消息队列异步执行 有大佬已经完成了这个拓展点了吗,求助!!! 消息队列是这两天看Bi项目的文档笔记现学的。 然后拉bi项目的源码看。搞了一个早上,思路很乱,不清楚生产者跟消费者具体要传什么message,晕了 先吃个饭 下午再整理一下思路,希望有大佬能指点一下😭
4
下载 APP