

1、代码片段 - 带入理解
一、核心模式分类
- 简单工厂模式(编程习惯,非 GoF 设计模式)
- 工厂方法模式(GoF 创建型模式)
- 抽象工厂模式(GoF 创建型模式)
二、演变过程:咖啡店案例
初始实现
java
// 咖啡基类
abstract class Coffee {
public abstract String getName();
}
class AmericanCoffee extends Coffee {}
class LatteCoffee extends Coffee {}
// 咖啡店直接创建对象
class CoffeeStore {
public Coffee orderCoffee(String type) {
if ("american".equals(type)) {
return new AmericanCoffee();
} else {
return new LatteCoffee();
}
}
}
问题 违反开闭原则,新增咖啡类型需修改订单方法
三、改进方案演变
1、简单工厂模式
java
class SimpleCoffeeFactory {
public Coffee createCoffee(String type) {
// 创建逻辑...
}
}
class CoffeeStore {
private SimpleCoffeeFactory factory;
public Coffee orderCoffee(String type) {
return factory.createCoffee(type);
}
}
- 优点 解耦对象创建
- 缺点 仍需修改工厂代码,违反开闭原则
2、工厂方法模式
java
interface CoffeeFactory {
Coffee createCoffee();
}
class AmericanFactory implements CoffeeFactory {
public Coffee createCoffee() { return new AmericanCoffee(); }
}
class CoffeeStore {
private CoffeeFactory factory;
public void setFactory(CoffeeFactory factory) {
this.factory = factory;
}
public Coffee orderCoffee() {
return factory.createCoffee();
}
}
- 优点 完全遵循开闭原则
- 缺点 类数量激增(类爆炸问题)
3、抽象工厂模式
java
interface DessertFactory {
Coffee createCoffee();
Dessert createDessert();
}
class AmericanDessertFactory implements DessertFactory {
public Coffee createCoffee() { return new AmericanCoffee(); }
public Dessert createDessert() { return new MatchaMousse(); }
}
- 优点 管理产品族(咖啡+甜点的组合)
- 代价 新增产品类型需修改所有工厂接口
4、模式对比表
模式特性 | 简单工厂 | 工厂方法 | 抽象工厂 |
---|---|---|---|
扩展性 | 修改工厂类 | 新增工厂子类 | 新增工厂实现类 |
产品维度 | 单一产品 | 单一产品 | 产品族(多相关产品) |
开闭原则 | 违反 | 遵循 | 部分遵循 |
复杂度 | 低 | 中 | 高 |
典型应用场景 | 简单对象创建 | 需要灵活扩展的产品创建 | 系列关联产品的组合创建 |
四、进阶应用技巧
1、静态工厂
java
class SimpleCoffeeFactory {
public static Coffee createCoffee(String type) {
// 创建逻辑...
}
}
2、配置化工厂
properties
# bean.properties
american=com.example.AmericanCoffee
latte=com.example.LatteCoffee
java
class ConfigFactory {
private static Map<String, Coffee> cache = new HashMap<>();
static {
// 加载配置文件,反射创建对象存入缓存
}
public static Coffee getCoffee(String key) {
return cache.get(key);
}
}
全部代码
java
public class CoffeeFactory {
// 加载配置文件, 获取配置文件中配置的全类名, 并创建该类的对象进行存储
// 1.定义容器对象用来存储咖啡对象
private static HashMap<String, Coffee> map = new HashMap<String, Coffee>();
// 2.加载配置文件, 只需要加载一次
static {
// 2.1 创建proper.ties 对象
Properties p = new Properties();
// 2.2调用p对象中的load 方法进行配置文件的加载 获取字节码 -> 获取类加载器 -> 获取目标资源(返回inputStream)
InputStream is = CoffeeFactory.class.getClassLoader().getResourceAsStream("bean.properties");
try {
// 加载资源
p.load(is);
// 从p集合中获取全类名并创建对象
Set<Object> keys = p.keySet();
for (Object key : keys) {
String className = p.getProperty((String) key);
// 通过反射创建对象
Class<?> clazz = Class.forName(className);
Coffee coffee = (Coffee) clazz.newInstance();// 创建对象
// 将名称和对象存储到容器中
map.put((String) key,coffee);
}
} catch (IOException | ClassNotFoundException | InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
}
// 根据名称获取对象
public static Coffee createCoffee(String name){
return map.get(name);
}
}
五、JDK典型案例
- 集合迭代器
java
// 工厂方法模式应用
Collection<String> coll = new ArrayList<>();
Iterator<String> it = coll.iterator(); // ArrayList内部实现Iterator
- 日期工具
java
Calendar cal = Calendar.getInstance(); // 根据时区返回不同实现
DateFormat df = DateFormat.getInstance();
2、文字提炼 - 记忆切入点
一、简单工厂模式
1、核心思想
将对象创建逻辑集中在一个"工厂类"中,通过 参数
控制具体产品类型。
-
关键步骤
-
定义产品接口
创建抽象基类(如
Coffee
),声明所有产品共有的方法(如getName()
) -
实现具体产品
继承基类创建具体产品(如
AmericanCoffee
和LatteCoffee
),各自实现特有逻辑 -
构建工厂类
创建
SimpleCoffeeFactory
类,内部包含静态/实例方法(如createCoffee(type)
),通过if-else
或switch
判断参数类型,返回对应的具体产品实例 -
客户端调用
客户端(如
CoffeeStore
)持有工厂引用,调用createCoffee()
时传入类型参数,无需直接接触具体产品类
-
-
典型特征
-
工厂类包含所有产品的创建逻辑
-
新增产品必须修改工厂类代码
-
二、工厂方法模式
2、核心思想
将对象的创建 延迟
到子类,每个产品对应一个专属工厂。
-
关键步骤
-
定义抽象工厂接口
创建
CoffeeFactory
接口,声明抽象方法(如createCoffee()
) -
实现具体工厂
为每个产品创建专属工厂类(如
AmericanCoffeeFactory
和LatteCoffeeFactory
),在createCoffee()
中返回对应的具体产品实例 -
客户端依赖抽象
客户端类(如
CoffeeStore
)持有工厂接口的引用,通过setFactory()
方法注入具体工厂 -
动态创建产品
客户端调用
factory.createCoffee()
时,实际执行的是具体工厂类中实现的创建逻辑
-
-
典型特征
-
每个产品对应一个独立工厂类
-
新增产品只需添加新工厂,无需修改已有代码
-
三、抽象工厂模式
2、核心思想
创建相关产品族的工厂,保证产品之间的兼容性。
-
关键步骤
-
定义产品族接口
创建多个抽象产品接口(如
Coffee: 咖啡
和Dessert: 甜点
),每个接口代表一类产品 -
定义抽象工厂接口
创建
DessertFactory: 甜点工厂
接口,声明创建系列产品的方法(如createCoffee()
和createDessert()
) -
实现具体工厂
为每个产品族创建工厂类(如
AmericanDessertFactory: 美式甜点工厂
),同时实现该族内 所有产品的创建逻辑 -
客户端组合使用
客户端通过选择具体工厂,获得配套的产品组合(如美式咖啡 + 抹茶慕斯),确保产品间的兼容性
-
-
典型特征
-
一个工厂创建多个关联产品
-
新增产品类型时, 需要修改所有工厂接口
-
四、工厂模式历史演进
- 简单工厂 解决直接
new
对象带来的耦合问题,但工厂本身成为新的耦合点 - 工厂方法 通过多态工厂解耦,支持扩展但容易产生类爆炸
- 抽象工厂 应对产品组合需求,用更高维度的抽象管理关联对象
五、记忆点 - 关键区别
-
考虑创建目标时
简单工厂
单一产品工厂方法
单一产品抽象工厂
产品族
-
考虑扩展代价时
简单工厂
修改工厂类工厂方法
新增工厂类抽象工厂
修改所有工厂接口
-
考虑设计重心时
简单工厂
创建逻辑集中化工厂方法
创建责任分散化抽象工厂
产品组合约束
提炼
模式选择指南
- 简单工厂 适用于对象创建逻辑简单,不需要频繁扩展
- 工厂方法 适合需要灵活扩展产品类型的场景
- 抽象工厂 适用于管理产品族,强调相关产品必须配套使用
关键设计原则体现
- 开闭原则 工厂方法模式的典型体现
- 单一职责 每个工厂只负责创建特定对象
- 依赖倒置 客户端依赖抽象接口而非具体实现
如果这篇文章帮到你, 帮忙点个关注呗, 不想那那那点赞或收藏也行鸭 (。•̀ᴗ-)✧ ~

'(இ﹏இ`。)