抽象工厂模式(Abstract Factory Pattern)
1. 概述
抽象工厂模式是一种创建型设计模式,它提供一个接口,用于创建一系列相关或互相依赖的对象,而无需指定具体的类。抽象工厂模式的核心思想是将具体产品的创建过程抽象化,从而使得产品族的生成可以通过工厂来控制和管理。
2. 适用场景
- 系统要独立于产品的创建和使用:希望通过一个接口来创建一系列相关的对象,并且这些对象可能属于不同的产品族。
- 系统要提供一组相互关联或依赖的对象:产品族中的对象之间有相关性或依赖关系。
- 系统有多个产品族:并且只消费其中某一族的产品,如跨平台的GUI程序,每个平台(Windows、Mac、Linux)都需要不同的一组控件。
3. 结构
- AbstractFactory(抽象工厂):声明一组创建产品的方法,每个方法对应一个产品。
- ConcreteFactory(具体工厂):实现
AbstractFactory
的接口,提供具体产品的生成逻辑。 - AbstractProduct(抽象产品):为每种产品类型声明接口。
- ConcreteProduct(具体产品):实现
AbstractProduct
接口,由具体工厂创建。 - Client(客户端):通过
AbstractFactory
接口创建产品,客户端通常只需要与抽象工厂和抽象产品接口交互。
4. 示例代码
假设我们要开发一个跨平台的GUI库,不同的操作系统(Windows、MacOS)有不同的UI控件(按钮和复选框)。我们可以使用抽象工厂模式来创建这些控件。
1. 定义抽象产品接口
interface Button {
void paint();
}
interface Checkbox {
void paint();
}
2. 实现具体产品类
class WindowsButton implements Button {
@Override
public void paint() {
System.out.println("Rendering a button in Windows style.");
}
}
class MacOSButton implements Button {
@Override
public void paint() {
System.out.println("Rendering a button in MacOS style.");
}
}
class WindowsCheckbox implements Checkbox {
@Override
public void paint() {
System.out.println("Rendering a checkbox in Windows style.");
}
}
class MacOSCheckbox implements Checkbox {
@Override
public void paint() {
System.out.println("Rendering a checkbox in MacOS style.");
}
}
3. 定义抽象工厂接口
interface GUIFactory {
Button createButton();
Checkbox createCheckbox();
}
4. 实现具体工厂类
class WindowsFactory implements GUIFactory {
@Override
public Button createButton() {
return new WindowsButton();
}
@Override
public Checkbox createCheckbox() {
return new WindowsCheckbox();
}
}
class MacOSFactory implements GUIFactory {
@Override
public Button createButton() {
return new MacOSButton();
}
@Override
public Checkbox createCheckbox() {
return new MacOSCheckbox();
}
}
5. 使用抽象工厂模式的客户端
public class AbstractFactoryDemo {
private Button button;
private Checkbox checkbox;
public AbstractFactoryDemo(GUIFactory factory) {
button = factory.createButton();
checkbox = factory.createCheckbox();
}
public void paint() {
button.paint();
checkbox.paint();
}
public static void main(String[] args) {
GUIFactory factory;
String os = "Windows"; // 这可以是通过配置文件或运行时参数决定
if (os.equals("Windows")) {
factory = new WindowsFactory();
} else {
factory = new MacOSFactory();
}
AbstractFactoryDemo app = new AbstractFactoryDemo(factory);
app.paint();
}
}
6. 运行结果
Rendering a button in Windows style.
Rendering a checkbox in Windows style.
7. 分析
- 解耦创建与使用:客户端无需了解具体产品类的创建逻辑,只需要通过抽象工厂接口来创建产品对象。
- 便于扩展:增加一个新的产品族只需添加一个新的具体工厂和一组产品实现,而无需修改现有的代码。
8. 优缺点
-
优点:
- 分离接口与实现:客户端通过抽象接口使用产品族,增加了系统的灵活性和可扩展性。
- 产品族的一致性:确保同一个产品族中的产品在外观或行为上保持一致,避免产品混用的问题。
- 便于扩展:新增产品族时,只需创建新的具体工厂和产品,不影响现有代码。
-
缺点:
- 增加系统复杂性:引入多个抽象类和接口,增加了系统的复杂度。
- 难以支持新产品类型:如果需要添加新的产品类型,则需要修改抽象工厂接口和所有具体工厂类。
9. 适用场景扩展
- 跨平台开发:创建跨平台应用程序时,使用抽象工厂模式来生成不同平台的UI组件。
- 数据库访问层:根据不同的数据库系统(如MySQL、Oracle),生成不同的数据库连接、查询器等对象。
- 插件系统:插件系统中,为不同的插件生成不同的一系列相关对象,使得插件之间的依赖关系可以被管理。
抽象工厂模式通过提供一个创建一系列相关或依赖对象的接口,实现了产品族之间的解耦和统一管理。它适用于需要创建一组相互关联的对象,并且对象的类型和种类在运行时才确定的场景。