Java抽象工厂模式
抽象工厂模式创建相关或依赖的对象族,无需指定具体类。
模式定义
意图:创建一系列相关或相互依赖对象的接口,无需指定具体类。
产品族概念
产品族是指同一工厂生产的不同类型产品:
Java
产品族
↓
┌──────┴──────┐
颶显器 键盘 遼鼠标
↓ ↓ ↓
PC系列 PC系列 PC系列
Mac系列 Mac系列 Mac系列
模式结构
产品接口
Java
// 显示器
public interface Monitor {
void display();
}
// 键盘
public interface Keyboard {
void type();
}
// 鼠标
public interface Mouse {
void click();
}
PC系列产品
Java
public class PCMonitor implements Monitor {
@Override
public void display() {
System.out.println("PC显示器");
}
}
public class PCKeyboard implements Keyboard {
@Override
public void type() {
System.out.println("PC键盘");
}
}
public class PCMouse implements Mouse {
@Override
public void click() {
System.out.println("PC鼠标");
}
}
Mac系列产品
Java
public class MacMonitor implements Monitor {
@Override
public void display() {
System.out.println("Mac显示器");
}
}
public class MacKeyboard implements Keyboard {
@Override
public void type() {
System.out.println("Mac键盘");
}
}
public class MacMouse implements Mouse {
@Override
public void click() {
System.out.println("Mac鼠标");
}
}
抽象工厂
Java
public interface ComputerFactory {
Monitor createMonitor();
Keyboard createKeyboard();
Mouse createMouse();
}
具体工厂
Java
public class PCFactory implements ComputerFactory {
@Override
public Monitor createMonitor() {
return new PCMonitor();
}
@Override
public Keyboard createKeyboard() {
return new PCKeyboard();
}
@Override
public Mouse createMouse() {
return new PCMouse();
}
}
public class MacFactory implements ComputerFactory {
@Override
public Monitor createMonitor() {
return new MacMonitor();
}
@Override
public Keyboard createKeyboard() {
return new MacKeyboard();
}
@Override
public Mouse createMouse() {
return new MacMouse();
}
}
使用示例
Java
public class Client {
private ComputerFactory factory;
public Client(ComputerFactory factory) {
this.factory = factory;
}
public void assemble() {
Monitor monitor = factory.createMonitor();
Keyboard keyboard = factory.createKeyboard();
Mouse mouse = factory.createMouse();
monitor.display();
keyboard.type();
mouse.click();
}
}
// 切换产品族只需更换工厂
Client pcClient = new Client(new PCFactory());
pcClient.assemble(); // 输出PC系列
Client macClient = new Client(new MacFactory());
macClient.assemble(); // 输出Mac系列
抽象工厂 vs 工厂方法
| 特性 | 抽象工厂 | 工厂方法 |
|---|---|---|
| 创建对象 | 产品族 | 单个产品 |
| 工厂方法数 | 多个 | 一个 |
| 产品维度 | 2维(族+类型) | 1维(类型) |
| 扩展产品族 | 新增工厂 | 不支持 |
| 扩展产品类型 | 修改工厂 | 新增工厂 |
扩展产品族
新增Linux系列产品:
Java
// Linux产品
public class LinuxMonitor implements Monitor { ... }
public class LinuxKeyboard implements Keyboard { ... }
public class LinuxMouse implements Mouse { ... }
// Linux工厂
public class LinuxFactory implements ComputerFactory {
@Override
public Monitor createMonitor() { return new LinuxMonitor(); }
@Override
public Keyboard createKeyboard() { return new LinuxKeyboard(); }
@Override
public Mouse createMouse() { return new LinuxMouse(); }
}
无需修改已有代码,符合开闭原则。
实际应用示例
text
// 数据库访问组件
public interface Connection {
void connect();
}
public interface Command {
void execute();
}
public interface ResultSet {
void process();
}
// 抽象工厂
public interface DbFactory {
Connection createConnection();
Command createCommand();
ResultSet createResultSet();
}
// MySQL工厂
public class MySqlFactory implements DbFactory { ... }
// Oracle工厂
public class OracleFactory implements DbFactory { ... }
// 切换数据库只需更换工厂
DbFactory factory = new MySqlFactory();
Connection conn = factory.createConnection();
Command cmd = factory.createCommand();
适用场景
- 需要创建产品族
- 产品之间有约束关系
- 需要切换产品族
- 不想让客户端知道具体产品类
注意事项
新增产品类型需修改所有工厂,违反开闭原则
新增产品族只需新增工厂,符合开闭原则
产品族内产品数量固定时使用效果最好
结合反射或配置可实现动态切换工厂
要点总结
- 抽象工厂创建产品族,保证产品一致性
- 工厂有多个方法,创建不同类型产品
- 切换产品族只需更换工厂对象
- 新增产品族容易,新增产品类型困难
- 适用于需要同时创建多个相关产品的场景
📝 发现内容有误?点击此处直接编辑