1. 抽象工厂模式的定义
抽象工厂模式(Abstract Factory Pattern) 是一种创建型设计模式,它的核心思想是: 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
- 解决工厂方法模式只能创建单一产品的局限性。
- 支持创建产品家族,确保产品之间的兼容性。
- 客户端与具体产品类解耦,只依赖抽象接口。
核心概念:
- 产品族(Product Family):一组相关或相互依赖的产品对象
- 产品等级结构(Product Hierarchy):同一类产品的不同实现
2. 抽象工厂模式的结构
抽象工厂模式主要包含以下角色:
- AbstractFactory(抽象工厂):定义创建一系列相关产品的接口。
- ConcreteFactory(具体工厂):实现抽象工厂接口,创建特定产品族的所有产品。
- AbstractProduct(抽象产品):定义产品对象的接口。
- ConcreteProduct(具体产品):实现抽象产品接口,属于特定产品族。
txt
Client
|
AbstractFactory (抽象)
|
ConcreteFactoryA --> ProductA1, ProductA2, ProductA3
ConcreteFactoryB --> ProductB1, ProductB2, ProductB3
特点:
- 每个具体工厂负责创建一个完整的产品族。
- 产品族内的产品相互配合,保证兼容性。
- 客户端只依赖抽象接口,不关心具体实现。
2.1 AbstractFactory 抽象工厂
java
public interface GUIFactory {
Button createButton();
Checkbox createCheckbox();
Menu createMenu();
}
2.2 ConcreteFactory 具体工厂
java
public class WinFactory implements GUIFactory {
@Override
public Button createButton() {
return new WinButton();
}
@Override
public Checkbox createCheckbox() {
return new WinCheckbox();
}
@Override
public Menu createMenu() {
return new WinMenu();
}
}
public class MacFactory implements GUIFactory {
@Override
public Button createButton() {
return new MacButton();
}
@Override
public Checkbox createCheckbox() {
return new MacCheckbox();
}
@Override
public Menu createMenu() {
return new MacMenu();
}
}
2.3 AbstractProduct 抽象产品
java
public interface Button {
void render();
void onClick();
}
public interface Checkbox {
void render();
void toggle();
}
public interface Menu {
void render();
void show();
}
2.4 ConcreteProduct 具体产品
java
public class WinButton implements Button {
@Override
public void render() {
System.out.println("渲染Windows风格按钮");
}
@Override
public void onClick() {
System.out.println("Windows按钮点击事件处理");
}
}
public class MacButton implements Button {
@Override
public void render() {
System.out.println("渲染Mac风格按钮");
}
@Override
public void onClick() {
System.out.println("Mac按钮点击事件处理");
}
}
2.5 Client 客户端
java
public class Application {
private Button button;
private Checkbox checkbox;
private Menu menu;
public Application(GUIFactory factory) {
this.button = factory.createButton();
this.checkbox = factory.createCheckbox();
this.menu = factory.createMenu();
}
public void renderUI() {
button.render();
checkbox.render();
menu.render();
}
public static void main(String[] args) {
GUIFactory factory;
String osName = System.getProperty("os.name").toLowerCase();
if (osName.contains("win")) {
factory = new WinFactory();
} else if (osName.contains("mac")) {
factory = new MacFactory();
} else {
throw new UnsupportedOperationException("不支持的操作系统");
}
Application app = new Application(factory);
app.renderUI();
}
}
3. 抽象工厂模式的优缺点
优点:
- 产品族一致性:确保创建的对象属于同一产品族,保证兼容性。
- 开闭原则:新增产品族无需修改已有代码,只需添加新的具体工厂。
- 客户端解耦:客户端只依赖抽象接口,不关心具体实现。
- 切换便捷:可以轻松切换整个产品家族。
缺点:
- 扩展产品等级困难:新增产品类型需要修改所有工厂接口和实现。
- 类数量膨胀:产品族数量×产品等级数量=类的总数量。
- 复杂性高:多重抽象增加理解和维护难度。
- 违反开闭原则:新增产品等级时需要修改抽象工厂接口。
4. 抽象工厂模式的设计思想
-
产品族一致性:确保同一产品族内的产品相互兼容。
-
接口隔离:客户端只依赖抽象工厂和抽象产品接口。
-
开闭原则:对扩展开放(新增产品族),对修改关闭(已有代码)。
-
依赖倒置:高层模块不依赖低层模块,都依赖抽象。
-
单一职责:每个具体工厂只负责创建一个产品族。
5. 一些问题
Q1: 抽象工厂模式与工厂方法模式的区别是什么?
A1:
- 工厂方法模式:一个工厂只创建一种产品,关注单个产品的创建
- 抽象工厂模式:一个工厂创建一族相关产品,关注产品家族的创建
- 核心区别:工厂方法强调"单一产品的多态创建",抽象工厂强调"产品族的一致性创建"
java
// 工厂方法:每个工厂只创建一种产品
ButtonFactory -> Button
CheckboxFactory -> Checkbox
// 抽象工厂:每个工厂创建一族产品
WinFactory -> WinButton, WinCheckbox, WinMenu
MacFactory -> MacButton, MacCheckbox, MacMenu
Q2: 抽象工厂模式在什么场景下不适用?
-
单一产品创建
- 解释:如果只需要创建单个产品,使用抽象工厂会增加不必要的复杂性。
- 例子:只需要创建按钮组件,不需要整套UI组件时,用简单工厂或工厂方法更合适。
-
产品族不稳定
- 解释:如果产品类型经常变化,抽象工厂的接口需要频繁修改。
- 例子:UI组件库经常新增或删除组件类型,会导致所有工厂接口都需要修改。
-
性能敏感场景
- 解释:多层抽象和工厂创建会带来额外的性能开销。
- 例子:游戏引擎中的高频对象创建,直接new对象可能比工厂创建更高效。
-
产品间无关联性
- 解释:如果产品之间没有关联性或兼容性要求,不需要产品族概念。
- 例子:创建独立的工具类对象,它们之间没有配合关系。