定义
- 抽象工厂模式是一种创建型设计模式
- 抽象工厂模式可以用于创建一组相关的对象,而无需指定具体的类
抽象工厂模式包含以下几个主要角色:
- 抽象工厂(Abstract Factory) :声明了一组用于创建不同产品对象的方法,这些方法的返回类型通常为抽象产品类型。
- 具体工厂(Concrete Factory) :实现抽象工厂中的抽象方法,负责创建具体的产品对象组合。
- 抽象产品(Abstract Product) :定义产品的公共接口,所有具体产品类都实现这个接口。
- 具体产品(Concrete Product) :实现抽象产品接口的具体类,代表不同类型的产品对象
业务
类图
classDiagram
direction LR
class Button {
<<interface>>
+paint()
}
class WindowsButton {
+paint()
}
class MacButton {
+paint()
}
class LinuxButton {
+paint()
}
class TextBox {
<<interface>>
+display()
}
class WindowsTextBox {
+display()
}
class MacTextBox {
+display()
}
class LinuxTextBox {
+display()
}
class Menu {
<<interface>>
+show()
}
class WindowsMenu {
+show()
}
class MacMenu {
+show()
}
class LinuxMenu {
+show()
}
class GUIFactory {
<<interface>>
+createButton(): Button
+createTextBox(): TextBox
+createMenu(): Menu
}
class WindowsFactory {
+createButton(): Button
+createTextBox(): TextBox
+createMenu(): Menu
}
class MacFactory {
+createButton(): Button
+createTextBox(): TextBox
+createMenu(): Menu
}
class LinuxFactory {
+createButton(): Button
+createTextBox(): TextBox
+createMenu(): Menu
}
Button <|-- WindowsButton
Button <|-- MacButton
Button <|-- LinuxButton
TextBox <|-- WindowsTextBox
TextBox <|-- MacTextBox
TextBox <|-- LinuxTextBox
Menu <|-- WindowsMenu
Menu <|-- MacMenu
Menu <|-- LinuxMenu
WindowsButton <-- WindowsFactory
WindowsTextBox <-- WindowsFactory
WindowsMenu <-- WindowsFactory
LinuxButton <-- LinuxFactory
LinuxTextBox <-- LinuxFactory
LinuxMenu <-- LinuxFactory
MacButton <-- MacFactory
MacTextBox <-- MacFactory
MacMenu <-- MacFactory
WindowsFactory --> GUIFactory
MacFactory --> GUIFactory
LinuxFactory --> GUIFactory
代码
假设我们正在开发一个图形用户界面(GUI)库,需要支持不同的操作系统,如 Windows、Mac 和 Linux。每个操作系统都有自己的特定风格的按钮、文本框和菜单。我们可以使用抽象工厂模式来创建这些不同操作系统的 GUI 组件。 首先,定义抽象产品接口:
interface Button {
void paint();
}
interface TextBox {
void display();
}
interface Menu {
void show();
}
然后,实现具体产品类:
Windows 风格的组件:
class WindowsButton implements Button {
@Override
public void paint() {
System.out.println("绘制 Windows 风格的按钮");
}
}
class WindowsTextBox implements TextBox {
@Override
public void display() {
System.out.println("显示 Windows 风格的文本框");
}
}
class WindowsMenu implements Menu {
@Override
public void show() {
System.out.println("展示 Windows 风格的菜单");
}
}
Mac 风格的组件:
class MacButton implements Button {
@Override
public void paint() {
System.out.println("绘制 Mac 风格的按钮");
}
}
class MacTextBox implements TextBox {
@Override
public void display() {
System.out.println("显示 Mac 风格的文本框");
}
}
class MacMenu implements Menu {
@Override
public void show() {
System.out.println("展示 Mac 风格的菜单");
}
}
Linux 风格的组件:
class LinuxButton implements Button {
@Override
public void paint() {
System.out.println("绘制 Linux 风格的按钮");
}
}
class LinuxTextBox implements TextBox {
@Override
public void display() {
System.out.println("显示 Linux 风格的文本框");
}
}
class LinuxMenu implements Menu {
@Override
public void show() {
System.out.println("展示 Linux 风格的菜单");
}
}
接下来,定义抽象工厂接口:
interface GUIFactory {
Button createButton();
TextBox createTextBox();
Menu createMenu();
}
然后,实现具体工厂类:
Windows 工厂:
class WindowsFactory implements GUIFactory {
@Override
public Button createButton() {
return new WindowsButton();
}
@Override
public TextBox createTextBox() {
return new WindowsTextBox();
}
@Override
public Menu createMenu() {
return new WindowsMenu();
}
}
Mac 工厂:
class MacFactory implements GUIFactory {
@Override
public Button createButton() {
return new MacButton();
}
@Override
public TextBox createTextBox() {
return new MacTextBox();
}
@Override
public Menu createMenu() {
return new MacMenu();
}
}
Linux 工厂:
class LinuxFactory implements GUIFactory {
@Override
public Button createButton() {
return new LinuxButton();
}
@Override
public TextBox createTextBox() {
return new LinuxTextBox();
}
@Override
public Menu createMenu() {
return new LinuxMenu();
}
}
在业务代码中,可以使用抽象工厂来创建不同操作系统的 GUI 组件:
public class Main {
public static void main(String[] args) {
GUIFactory factory;
// 创建 Windows 风格的 GUI 组件
factory = new WindowsFactory();
Button button = factory.createButton();
TextBox textBox = factory.createTextBox();
Menu menu = factory.createMenu();
button.paint();
textBox.display();
menu.show();
// 创建 Mac 风格的 GUI 组件
factory = new MacFactory();
button = factory.createButton();
textBox = factory.createTextBox();
menu = factory.createMenu();
button.paint();
textBox.display();
menu.show();
// 创建 Linux 风格的 GUI 组件
factory = new LinuxFactory();
button = factory.createButton();
textBox = factory.createTextBox();
menu = factory.createMenu();
button.paint();
textBox.display();
menu.show();
}
}
优点
- 易于切换产品系列。如果需要切换到不同的操作系统风格的 GUI 组件,只需要更换具体工厂即可,客户端代码无需修改。
- 代码结构更加清晰。将不同操作系统的 GUI 组件的创建逻辑封装在不同的工厂类中,使得代码的职责更加明确。
缺点
-
难以支持新的产品种类。如果需要添加一种新的 GUI 组件,比如进度条,需要修改所有的具体工厂类和抽象工厂接口,这可能会导致较大的修改成本。
在框架中的使用
java
java swing图形用户界面库,类似上述java业务
spring
无 如 PlatformTransactionManager、DataSourceTransactionManager 只生成一个对象,属于工厂方法模式
mybatis
无
总结
抽象工厂 + 每个工厂生产多种产品
总的来说,抽象工厂模式适用于创建一组相关的对象,且这些对象的创建逻辑比较复杂,需要根据不同的情况进行切换的场景。
| 设计模式 | 对比1 | 对比2 |
|---|---|---|
| 简单工厂模式 | 没有抽象工厂,创建时直接生成的对象指定具体类 | 一个工厂创建一种对象 |
| 工厂方法模式 | 引入抽象工厂,创建时直接生成的对象指定抽象类(接口) | 一个工厂创建一种对象 |
| 抽象工厂模式 | 引入抽象工厂,创建时直接生成的对象指定抽象类(接口) | 一个工厂创建多种对象 |