文章目录
- 一、前言🚀🚀🚀
- 二、工厂方法模式简介及应用场景:☀️☀️☀️
- [1. 工厂方法模式(Factory Method Pattern)核心解读](#1. 工厂方法模式(Factory Method Pattern)核心解读)
-
- [1.1 通俗理解](#1.1 通俗理解)
- [1.2 核心角色(4个)](#1.2 核心角色(4个))
- [1.3 核心优势](#1.3 核心优势)
- [2. 工厂方法模式在Java中的典型示例(手机创建场景)](#2. 工厂方法模式在Java中的典型示例(手机创建场景))
-
- [2.1 反例:不用工厂方法模式(耦合严重)](#2.1 反例:不用工厂方法模式(耦合严重))
- [2.2 正例:用工厂方法模式重构(大厂标准写法)](#2.2 正例:用工厂方法模式重构(大厂标准写法))
- [2.3 Spring环境下的进阶写法(大厂实战)](#2.3 Spring环境下的进阶写法(大厂实战))
- [3. 工厂方法模式的典型应用场景(大厂高频)](#3. 工厂方法模式的典型应用场景(大厂高频))
-
- [3.1 多产品系列创建](#3.1 多产品系列创建)
- [3.2 算法/接口适配](#3.2 算法/接口适配)
- [3.3 框架内置的工厂方法模式](#3.3 框架内置的工厂方法模式)
- [4. 大厂为什么重视设计模式?](#4. 大厂为什么重视设计模式?)
-
- [4.1 解决大规模代码的维护性问题](#4.1 解决大规模代码的维护性问题)
- [4.2 支撑高扩展的业务需求](#4.2 支撑高扩展的业务需求)
- [4.3 实现代码复用+标准化](#4.3 实现代码复用+标准化)
- [4.4 适配高并发/高可用架构](#4.4 适配高并发/高可用架构)
- [5. 总结](#5. 总结)
一、前言🚀🚀🚀

☀️
你每一天的努力会在未来的某一个点交汇成宏伟的画面。
本文简介:这是一篇关于设计模式,小编在学习设计模式式,很疑惑这种纯概念的东西如何在实际编码中应用呢,可能是没有接触过大的项目,没有大佬带,好奇心驱使下,于是出现了这篇跟AI对话的学习报刊。 欢迎大佬们评论或私信斧正 Thanks♪(・ω・)
二、工厂方法模式简介及应用场景:☀️☀️☀️
不积跬步无以至千里,不积小流无以成江河。欢迎交流~
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 生成)