抽象工厂模式
创建型模式
访问次数: 12
抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
视频教程
类图
classDiagram
class AbstractFactory {
<<interface>>
+createProductA() AbstractProductA
+createProductB() AbstractProductB
}
class ConcreteFactory1 {
+createProductA() AbstractProductA
+createProductB() AbstractProductB
}
class ConcreteFactory2 {
+createProductA() AbstractProductA
+createProductB() AbstractProductB
}
class AbstractProductA {
<<interface>>
+operationA()
}
class AbstractProductB {
<<interface>>
+operationB()
}
class ProductA1 {
+operationA()
}
class ProductA2 {
+operationA()
}
class ProductB1 {
+operationB()
}
class ProductB2 {
+operationB()
}
AbstractFactory <|-- ConcreteFactory1
AbstractFactory <|-- ConcreteFactory2
AbstractProductA <|-- ProductA1
AbstractProductA <|-- ProductA2
AbstractProductB <|-- ProductB1
AbstractProductB <|-- ProductB2
ConcreteFactory1 --> ProductA1
ConcreteFactory1 --> ProductB1
ConcreteFactory2 --> ProductA2
ConcreteFactory2 --> ProductB2
源代码示例
// 抽象产品A
interface AbstractProductA {
void operationA();
}
// 抽象产品B
interface AbstractProductB {
void operationB();
}
// 具体产品A1
class ProductA1 implements AbstractProductA {
@Override
public void operationA() {
System.out.println("ProductA1 operationA");
}
}
// 具体产品A2
class ProductA2 implements AbstractProductA {
@Override
public void operationA() {
System.out.println("ProductA2 operationA");
}
}
// 具体产品B1
class ProductB1 implements AbstractProductB {
@Override
public void operationB() {
System.out.println("ProductB1 operationB");
}
}
// 具体产品B2
class ProductB2 implements AbstractProductB {
@Override
public void operationB() {
System.out.println("ProductB2 operationB");
}
}
// 抽象工厂
interface AbstractFactory {
AbstractProductA createProductA();
AbstractProductB createProductB();
}
// 具体工厂1
class ConcreteFactory1 implements AbstractFactory {
@Override
public AbstractProductA createProductA() {
return new ProductA1();
}
@Override
public AbstractProductB createProductB() {
return new ProductB1();
}
}
// 具体工厂2
class ConcreteFactory2 implements AbstractFactory {
@Override
public AbstractProductA createProductA() {
return new ProductA2();
}
@Override
public AbstractProductB createProductB() {
return new ProductB2();
}
}
# 抽象产品A
from abc import ABC, abstractmethod
class AbstractProductA(ABC):
@abstractmethod
def operation_a(self):
pass
# 抽象产品B
class AbstractProductB(ABC):
@abstractmethod
def operation_b(self):
pass
# 具体产品A1
class ProductA1(AbstractProductA):
def operation_a(self):
print("ProductA1 operationA")
# 具体产品A2
class ProductA2(AbstractProductA):
def operation_a(self):
print("ProductA2 operationA")
# 具体产品B1
class ProductB1(AbstractProductB):
def operation_b(self):
print("ProductB1 operationB")
# 具体产品B2
class ProductB2(AbstractProductB):
def operation_b(self):
print("ProductB2 operationB")
# 抽象工厂
class AbstractFactory(ABC):
@abstractmethod
def create_product_a(self):
pass
@abstractmethod
def create_product_b(self):
pass
# 具体工厂1
class ConcreteFactory1(AbstractFactory):
def create_product_a(self):
return ProductA1()
def create_product_b(self):
return ProductB1()
# 具体工厂2
class ConcreteFactory2(AbstractFactory):
def create_product_a(self):
return ProductA2()
def create_product_b(self):
return ProductB2()
# 使用示例
if __name__ == "__main__":
factory1 = ConcreteFactory1()
factory2 = ConcreteFactory2()
product_a1 = factory1.create_product_a()
product_b1 = factory1.create_product_b()
product_a1.operation_a()
product_b1.operation_b()
应用场景
当需要创建一系列相关的产品,且这些产品需要一起使用时。应用场景包括:
1)UI组件库中,需要为不同主题(Windows风格、Mac风格、Linux风格)创建配套的按钮、文本框、菜单等组件
2)数据库访问层中,为不同数据库(MySQL、Oracle、PostgreSQL)创建对应的连接、命令、数据适配器等组件
3)跨平台应用中,为不同操作系统(Windows、macOS、Linux)创建对应的窗口、菜单、对话框等界面元素
4)游戏引擎中,为不同渲染API(DirectX、OpenGL、Vulkan)创建对应的着色器、纹理、缓冲区等渲染组件
5)消息系统中,为不同消息协议(HTTP、WebSocket、MQTT)创建对应的连接器、序列化器、传输器等组件
精选场景详解 —— UI 组件库:按主题创建配套控件族
问题背景
同一套界面要在「Windows 风格 / Mac 风格」间切换。按钮、文本框、菜单必须成套一致;若分别 new,容易出现 Win 按钮配 Mac 菜单的「混搭」问题。
模式如何解决
选用抽象工厂:AbstractUIFactory 声明 createButton、createTextBox、createMenu 等一族创建方法。WinFactory / MacFactory 各自返回风格一致的产品族。
核心价值:
1)保证产品族约束(同一工厂产出的控件风格统一);
2)切换主题只需替换工厂实例,客户端代码几乎不动;
3)抽象与具体产品解耦,便于主题扩展。
适用前提:产品之间有「配套关系」。若只需创建单一产品且无族约束,工厂方法往往更简单。
场景模型(角色映射)
将模式中的抽象角色映射到该业务领域的具体类:
classDiagram
class UIFactory {
<<interface>>
+createButton() Button
+createTextBox() TextBox
+createMenu() Menu
}
class WinFactory {
+createButton() Button
+createTextBox() TextBox
+createMenu() Menu
}
class MacFactory {
+createButton() Button
+createTextBox() TextBox
+createMenu() Menu
}
class Button {
<<interface>>
+render()
}
class WinButton {
+render()
}
class MacButton {
+render()
}
class TextBox {
<<interface>>
+render()
}
class Application {
-factory: UIFactory
+buildUI()
}
UIFactory <|.. WinFactory
UIFactory <|.. MacFactory
Button <|.. WinButton
Button <|.. MacButton
WinFactory --> WinButton
MacFactory --> MacButton
Application --> UIFactory
Application --> Button