1、代码片段 - 带入理解
一、核心模式分类
- 简单工厂模式(编程习惯,非 GoF 设计模式)
- 工厂方法模式(GoF 创建型模式)
- 抽象工厂模式(GoF 创建型模式)
二、演变过程:咖啡店案例
初始实现
// 咖啡基类
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、简单工厂模式
class SimpleCoffeeFactory {
public Coffee createCoffee(String type) {
// 创建逻辑...
}
}
class CoffeeStore {
private SimpleCoffeeFactory factory;
public Coffee orderCoffee(String type) {
return factory.createCoffee(type);
}
}
- 优点 解耦对象创建
- 缺点 仍需修改工厂代码,违反开闭原则
2、工厂方法模式
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、抽象工厂模式
interface DessertFactory {
Coffee createCoffee();
Dessert createDessert();
}
class AmericanDessertFactory implements DessertFactory {
public Coffee createCoffee() { return new AmericanCoffee(); }
public Dessert createDessert() { return new MatchaMousse(); }
}
- 优点 管理产品族(咖啡+甜点的组合)
- 代价 新增产品类型需修改所有工厂接口
4、模式对比表
模式特性 | 简单工厂 | 工厂方法 | 抽象工厂 |
---|---|---|---|
扩展性 | 修改工厂类 | 新增工厂子类 | 新增工厂实现类 |
产品维度 | 单一产品 | 单一产品 | 产品族(多相关产品) |
开闭原则 | 违反 | 遵循 | 部分遵循 |
复杂度 | 低 | 中 | 高 |
典型应用场景 | 简单对象创建 | 需要灵活扩展的产品创建 | 系列关联产品的组合创建 |
四、进阶应用技巧
1、静态工厂
class SimpleCoffeeFactory {
public static Coffee createCoffee(String type) {
// 创建逻辑...
}
}
2、配置化工厂
# bean.properties
american=com.example.AmericanCoffee
latte=com.example.LatteCoffee
class ConfigFactory {
private static Map<String, Coffee> cache = new HashMap<>();
static {
// 加载配置文件,反射创建对象存入缓存
}
public static Coffee getCoffee(String key) {
return cache.get(key);
}
}
全部代码
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典型案例
- 集合迭代器
// 工厂方法模式应用
Collection<String> coll = new ArrayList<>();
Iterator<String> it = coll.iterator(); // ArrayList内部实现Iterator
- 日期工具
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
对象带来的耦合问题,但工厂本身成为新的耦合点 - 工厂方法 通过多态工厂解耦,支持扩展但容易产生类爆炸
- 抽象工厂 应对产品组合需求,用更高维度的抽象管理关联对象
五、记忆点 - 关键区别
考虑创建目标时
简单工厂
单一产品工厂方法
单一产品抽象工厂
产品族
考虑扩展代价时
简单工厂
修改工厂类工厂方法
新增工厂类抽象工厂
修改所有工厂接口
考虑设计重心时
简单工厂
创建逻辑集中化工厂方法
创建责任分散化抽象工厂
产品组合约束
提炼
模式选择指南
- 简单工厂 适用于对象创建逻辑简单,不需要频繁扩展
- 工厂方法 适合需要灵活扩展产品类型的场景
- 抽象工厂 适用于管理产品族,强调相关产品必须配套使用
关键设计原则体现
- 开闭原则 工厂方法模式的典型体现
- 单一职责 每个工厂只负责创建特定对象
- 依赖倒置 客户端依赖抽象接口而非具体实现
如果这篇文章帮到你, 帮忙点个关注呗, 不想那那那点赞或收藏也行鸭 (。•̀ᴗ-)✧ ~
'(இ﹏இ`。)