编程自学指南:java程序设计开发,Java 抽象工厂模式详解
一、课程信息
学习目标
- 理解抽象工厂模式的核心思想:创建多个产品族的相关对象
- 掌握四大核心角色的设计方法
- 能区分抽象工厂与工厂方法的差异,避免设计冗余
- 运用抽象工厂模式实现跨产品族的扩展
二、课程导入:生活中的 "全能工厂"
🌰 场景模拟:家具定制
- 传统方式:用工厂方法模式为每种家具(椅子、沙发)创建独立工厂
- 问题:新增家具风格(现代→北欧)需修改所有工厂类
- 抽象工厂方案:定义 "风格工厂",每个工厂负责生产同一风格的多种家具
三、核心概念与角色
1. 模式定义
提供一个创建 多个相关产品族 的接口,无需指定具体类。
核心:将产品族的创建抽象化,通过多态支持不同产品组合
2. 四大核心角色
角色名称 | 作用 | 家具案例类比 |
---|---|---|
抽象工厂 | 声明创建多个产品的抽象方法 | FurnitureFactory (造椅子 + 沙发) |
具体工厂 | 实现抽象工厂,创建特定产品族 | ModernFactory (造现代椅 + 现代沙发) |
抽象产品 | 定义产品公共接口 | Chair 、Sofa 接口 |
具体产品 | 实现抽象产品,属于某个产品族 | ModernChair 、TraditionalSofa |
四、实现步骤与基础案例
🔧 案例 1:家具工厂(产品族:现代 vs 传统)
步骤 1:定义抽象产品(2 个产品等级)
// 抽象产品1:椅子
interface Chair {
void sitOn();
}
// 抽象产品2:沙发
interface Sofa {
void lieOn();
}
步骤 2:实现具体产品(2 个产品族)
// 现代风格产品
class ModernChair implements Chair {
public void sitOn() { System.out.println("坐在现代简约椅上"); }
}
class ModernSofa implements Sofa {
public void lieOn() { System.out.println("躺在现代布艺沙发上"); }
}
// 传统风格产品
class TraditionalChair implements Chair {
public void sitOn() { System.out.println("坐在红木椅上"); }
}
class TraditionalSofa implements Sofa {
public void lieOn() { System.out.println("躺在真皮沙发上"); }
}
步骤 3:定义抽象工厂
interface FurnitureFactory {
Chair createChair(); // 创建椅子
Sofa createSofa(); // 创建沙发
}
步骤 4:实现具体工厂(绑定产品族)
// 现代家具工厂(生产现代风格的椅子+沙发)
class ModernFactory implements FurnitureFactory {
public Chair createChair() { return new ModernChair(); }
public Sofa createSofa() { return new ModernSofa(); }
}
// 传统家具工厂(生产传统风格的椅子+沙发)
class TraditionalFactory implements FurnitureFactory {
public Chair createChair() { return new TraditionalChair(); }
public Sofa createSofa() { return new TraditionalSofa(); }
}
步骤 5:客户端调用
public class Client {
public static void main(String[] args) {
// 选择现代风格工厂
FurnitureFactory factory = new ModernFactory();
Chair chair = factory.createChair();
Sofa sofa = factory.createSofa();
chair.sitOn(); // 输出:坐在现代简约椅上
sofa.lieOn(); // 输出:躺在现代布艺沙发上
// 切换传统风格工厂
factory = new TraditionalFactory();
chair = factory.createChair();
sofa = factory.createSofa();
chair.sitOn(); // 输出:坐在红木椅上
sofa.lieOn(); // 输出:躺在真皮沙发上
}
}
五、进阶案例:咖啡店系统
需求:支持不同风味的咖啡 + 甜点(意式 vs 美式)
1. 抽象产品(2 个等级)
// 抽象咖啡
abstract class Coffee {
abstract String getName();
void addMilk() { System.out.println("加奶"); }
}
// 抽象甜点
abstract class Dessert {
abstract void show();
}
2. 具体产品(2 个族)
// 意式族
class Latte extends Coffee {
String getName() { return "拿铁"; }
}
class Tiramisu extends Dessert {
void show() { System.out.println("提拉米苏"); }
}
// 美式族
class Americano extends Coffee {
String getName() { return "美式咖啡"; }
}
class Cheesecake extends Dessert {
void show() { System.out.println("芝士蛋糕"); }
}
3. 抽象工厂与具体工厂
interface CoffeeFactory {
Coffee createCoffee();
Dessert createDessert();
}
class ItalianFactory implements CoffeeFactory {
public Coffee createCoffee() { return new Latte(); }
public Dessert createDessert() { return new Tiramisu(); }
}
class AmericanFactory implements CoffeeFactory {
public Coffee createCoffee() { return new Americano(); }
public Dessert createDessert() { return new Cheesecake(); }
}
六、抽象工厂 vs 工厂方法
特性 | 工厂方法模式 | 抽象工厂模式 |
---|---|---|
产品范围 | 单个产品等级(如只造椅子) | 多个产品等级(造椅子 + 沙发) |
扩展性 | 新增产品等级需改抽象工厂 | 新增产品族只需加新工厂 |
复杂度 | 低 | 中(类数量更多) |
七、适用场景与优缺点
✅ 优点
- 产品族统一:保证同一工厂的产品相互兼容
- 解耦:客户端不依赖具体产品类
- 符合开闭原则:新增产品族容易
⚠️ 缺点
- 扩展产品等级困难:新增产品类型(如茶几)需修改所有抽象工厂接口
🔥 适用场景
- 跨平台 UI:为 Windows 和 Mac 创建按钮 + 文本框
- 游戏开发:创建不同主题的角色 + 武器(中世纪族、未来族)
八、课堂练习
练习 1:扩展家具工厂
需求:新增 "北欧风格" 家具族,包含NordicChair
和NordicSofa
练习 2:优化数据库工厂
原需求:支持 MySQL 和 Oracle 的Connection
和Statement
要求:用抽象工厂模式实现,客户端可动态切换数据库
九、课程总结
知识图谱:
抽象工厂模式
↳ 核心:创建多个产品族,绑定相关产品
↳ 角色:抽象工厂→具体工厂→抽象产品→具体产品
↳ 与工厂方法区别:处理多产品等级 vs 单产品等级
口诀记忆:
“抽象工厂管家族,多个产品一起造,
工厂方法是子集,等级扩展要记牢,
产品族内全兼容,开闭原则贯彻好!”
十、课后作业
必做 1:实现电器工厂
需求:
- 产品族:海尔(电视 + 冰箱)、格力(空调 + 洗衣机)
- 每个产品族包含 2 种产品,用抽象工厂模式实现
必做 2:分析 Spring 的 BeanFactory
任务:对比 Spring 的BeanFactory
与抽象工厂模式的异同