编程自学指南:java程序设计开发,Java 工厂方法设计模式详解课件
一、课程信息
学习目标
- 理解工厂方法模式的核心思想:将对象创建延迟到子类
- 掌握四大核心角色的设计方法
- 能通过工厂方法模式优化代码,避免
if-else
冗余 - 区分工厂方法与简单工厂的差异及适用场景
二、课程导入:生活中的工厂
🌰 场景模拟:汽车生产
- 传统方式:用户直接 new 不同类型的车(
new ElectricCar()
) - 问题:新增车型需修改所有创建代码,违反开闭原则
- 工厂方法方案:定义统一工厂接口,每种车由独立工厂生产
三、核心概念与角色
1. 模式定义
定义一个创建对象的接口,让子类决定实例化哪个类。
核心:将对象创建过程抽象化,通过多态实现扩展
2. 四大核心角色
角色名称 | 作用 | 类比造车厂案例 |
---|---|---|
抽象产品 | 定义产品公共接口 / 抽象类 | Car 接口(有drive() 方法) |
具体产品 | 实现抽象产品的具体类 | ElectricCar 、GasCar |
抽象工厂 | 声明创建产品的抽象方法 | CarFactory 接口(createCar() ) |
具体工厂 | 实现抽象工厂,创建具体产品 | ElectricCarFactory 、GasCarFactory |
四、实现步骤与案例
🔧 案例 1:造车厂系统
步骤 1:定义抽象产品
// 抽象产品:所有车都能驾驶
public interface Car {
void drive();
}
步骤 2:实现具体产品
// 具体产品:电动车
public class ElectricCar implements Car {
@Override
public void drive() {
System.out.println("驾驶电动车,安静环保");
}
}
// 具体产品:燃油车
public class GasCar implements Car {
@Override
public void drive() {
System.out.println("驾驶燃油车,动力强劲");
}
}
步骤 3:定义抽象工厂
// 抽象工厂:声明造车方法
public interface CarFactory {
Car createCar();
}
步骤 4:实现具体工厂
// 电动车工厂
public class ElectricCarFactory implements CarFactory {
@Override
public Car createCar() {
return new ElectricCar();
}
}
// 燃油车工厂
public class GasCarFactory implements CarFactory {
@Override
public Car createCar() {
return new GasCar();
}
}
步骤 5:客户端调用
public class Client {
public static void main(String[] args) {
// 选择电动车工厂
CarFactory factory = new ElectricCarFactory();
Car car = factory.createCar();
car.drive(); // 输出:驾驶电动车,安静环保
// 新增燃油车只需换工厂
factory = new GasCarFactory();
car = factory.createCar();
car.drive(); // 输出:驾驶燃油车,动力强劲
}
}
📐 对比:简单工厂 vs 工厂方法
特性 | 简单工厂模式 | 工厂方法模式 |
---|---|---|
核心类 | 一个工厂类负责所有产品创建 | 每个产品有独立工厂类 |
扩展性 | 新增产品需修改工厂类(违反开闭) | 新增产品只需添加新工厂和产品类 |
典型场景 | 产品种类少且稳定 | 产品种类多或频繁扩展 |
五、进阶案例:日志系统设计
需求:支持多种日志类型(文件日志、数据库日志)
1. 抽象产品:日志记录器
public interface Logger {
void log(String message);
}
2. 具体产品
// 文件日志
public class FileLogger implements Logger {
@Override
public void log(String message) {
System.out.println("写入文件:" + message);
}
}
// 数据库日志
public class DatabaseLogger implements Logger {
@Override
public void log(String message) {
System.out.println("写入数据库:" + message);
}
}
3. 抽象工厂与具体工厂
public interface LoggerFactory {
Logger createLogger();
}
public class FileLoggerFactory implements LoggerFactory {
@Override
public Logger createLogger() {
return new FileLogger();
}
}
public class DatabaseLoggerFactory implements LoggerFactory {
@Override
public Logger createLogger() {
return new DatabaseLogger();
}
}
4. 客户端动态选择
public class App {
public static void main(String[] args) {
// 配置中心获取日志类型(模拟从配置文件读取)
String loggerType = "database";
LoggerFactory factory = null;
if ("file".equals(loggerType)) {
factory = new FileLoggerFactory();
} else if ("database".equals(loggerType)) {
factory = new DatabaseLoggerFactory();
}
Logger logger = factory.createLogger();
logger.log("用户登录成功");
}
}
六、优缺点与适用场景
✅ 优点
- 开闭原则:新增产品只需扩展工厂和产品类,无需修改原有代码
- 解耦:客户端与具体产品类解耦,只依赖抽象接口
- 职责单一:每个工厂专注创建一种产品
⚠️ 缺点
- 类数量增加:每个产品对应一个工厂类,可能导致类爆炸
- 复杂度提升:简单场景使用会增加代码复杂度
🔥 适用场景
- 产品族扩展:如电商平台支持多种支付方式(支付宝、微信支付)
- 跨平台开发:根据不同操作系统创建不同组件(Windows 按钮 vs Mac 按钮)
- 框架设计:Spring 的
BeanFactory
、MyBatis 的SqlSessionFactory
七、课堂练习
练习 1:扩展造车厂案例
需求:新增混合动力车HybridCar
,使用工厂方法模式实现
练习 2:优化用户注册逻辑
原代码:
if ("student".equals(type)) {
new StudentUser();
} else if ("teacher".equals(type)) {
new TeacherUser();
}
要求:用工厂方法模式重构,消除if-else
八、课程总结
知识图谱:
工厂方法模式
↳ 四大角色:抽象产品、具体产品、抽象工厂、具体工厂
↳ 核心思想:通过多态延迟对象创建
↳ 优势:开闭原则、解耦、职责单一
↳ 与简单工厂区别:工厂类是否可扩展
口诀记忆:
“工厂方法真奇妙,创建对象不用 new,
抽象工厂定规范,具体工厂造产品,
新增产品不修改,实现扩展很优雅!”
九、课后作业
必做 1:实现动物工厂
需求:
- 定义
Animal
接口(有voice()
方法) - 实现
Dog
、Cat
具体类 - 为每种动物创建独立工厂类
- 客户端通过工厂创建动物并调用叫声
必做 2:分析 JDK 中的工厂方法
任务:查看java.util.Calendar
类源码,说明它如何使用工厂方法模式