元素码农
基础
UML建模
数据结构
算法
设计模式
网络
TCP/IP协议
HTTPS安全机制
WebSocket实时通信
数据库
sqlite
postgresql
clickhouse
后端
rust
go
java
php
mysql
redis
mongodb
etcd
nats
zincsearch
前端
浏览器
javascript
typescript
vue3
react
游戏
unity
unreal
C++
C#
Lua
App
android
ios
flutter
react-native
安全
Web安全
测试
软件测试
自动化测试 - Playwright
人工智能
Python
langChain
langGraph
运维
linux
docker
工具
git
svn
🌞
🌙
目录
▶
设计原则
单一职责原则
开闭原则
里氏替换原则
依赖倒置原则
接口隔离原则
迪米特法则
▶
创建型模式
工厂方法模式
抽象工厂
单例模式
建造者模式
原型模式
▶
结构型模式
适配器模式
装饰器模式
代理模式
外观模式
组合模式
桥接模式
享元模式
▶
行为型模式
策略模式
观察者模式
命令模式
模板方法模式
状态模式
责任链模式
迭代器模式
中介者模式
访问者模式
备忘录模式
解释器模式
发布时间:
2025-03-21 10:57
↑
☰
# 抽象工厂模式 ## 定义 抽象工厂模式(Abstract Factory Pattern)是一种创建型设计模式,它提供一个接口用于创建一系列相关或相互依赖的对象,而无需指定它们的具体类。抽象工厂模式与工厂方法模式的主要区别在于:抽象工厂模式创建的是一系列相关的产品族,而工厂方法模式创建的是单一产品。 ## 适用场景 - 需要创建一系列相关或相互依赖的对象时 - 系统需要独立于产品的创建、组合和表示时 - 系统需要提供一个产品类的库,只显示接口而不显示实现时 - 产品族的版本需要统一变化时 ## 结构图 ```mermaid 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 ``` ## 实现示例 以游戏UI主题系统为例,我们需要为游戏创建不同风格(如暗黑风格和明亮风格)的UI组件(按钮和文本框)。 ```go package abstractfactory // 抽象产品接口 - 按钮 type Button interface { Render() string OnClick() } // 抽象产品接口 - 文本框 type TextBox interface { Render() string OnInput(text string) } // 抽象工厂接口 type UIFactory interface { CreateButton() Button CreateTextBox() TextBox } // 具体产品 - 暗黑风格按钮 type DarkButton struct{} func (b *DarkButton) Render() string { return "渲染暗黑风格按钮" } func (b *DarkButton) OnClick() { println("暗黑风格按钮被点击") } // 具体产品 - 暗黑风格文本框 type DarkTextBox struct{} func (t *DarkTextBox) Render() string { return "渲染暗黑风格文本框" } func (t *DarkTextBox) OnInput(text string) { println("暗黑风格文本框输入:", text) } // 具体产品 - 明亮风格按钮 type LightButton struct{} func (b *LightButton) Render() string { return "渲染明亮风格按钮" } func (b *LightButton) OnClick() { println("明亮风格按钮被点击") } // 具体产品 - 明亮风格文本框 type LightTextBox struct{} func (t *LightTextBox) Render() string { return "渲染明亮风格文本框" } func (t *LightTextBox) OnInput(text string) { println("明亮风格文本框输入:", text) } // 具体工厂 - 暗黑风格UI工厂 type DarkUIFactory struct{} func (f *DarkUIFactory) CreateButton() Button { return &DarkButton{} } func (f *DarkUIFactory) CreateTextBox() TextBox { return &DarkTextBox{} } // 具体工厂 - 明亮风格UI工厂 type LightUIFactory struct{} func (f *LightUIFactory) CreateButton() Button { return &LightButton{} } func (f *LightUIFactory) CreateTextBox() TextBox { return &LightTextBox{} } // 客户端代码 type Application struct { factory UIFactory button Button textbox TextBox } func NewApplication(factory UIFactory) *Application { app := &Application{ factory: factory, } app.createUI() return app } func (app *Application) createUI() { app.button = app.factory.CreateButton() app.textbox = app.factory.CreateTextBox() } func (app *Application) RenderUI() { println(app.button.Render()) println(app.textbox.Render()) } ``` 使用示例: ```go func main() { // 创建暗黑主题应用 darkApp := NewApplication(&DarkUIFactory{}) darkApp.RenderUI() // 创建明亮主题应用 lightApp := NewApplication(&LightUIFactory{}) lightApp.RenderUI() } ``` ## 优缺点分析 ### 优点 1. **产品族一致性** - 确保客户端始终只使用同一个产品族中的对象 - 所有产品都遵循相同的主题或风格 2. **解耦性** - 将产品的创建与使用完全分离 - 客户端代码不需要知道具体产品的类 3. **易于扩展** - 添加新的产品族只需要实现新的工厂和产品类 - 不需要修改现有代码,符合开闭原则 ### 缺点 1. **复杂性增加** - 需要定义大量的接口和类 - 系统的抽象层次和类的层次都会增加 2. **扩展困难** - 添加新的产品类型需要修改抽象工厂接口 - 所有具体工厂都需要实现新的方法 3. **产品族扩展受限** - 产品族中的产品数量是固定的 - 增加新的产品类型需要修改所有的工厂类 ## 最佳实践 1. **合理划分产品族** - 仔细分析产品之间的关系 - 确保产品族中的产品真正相关 2. **接口设计** - 保持抽象工厂接口简单清晰 - 避免在接口中定义太多方法 3. **工厂方法的选择** - 当只需要创建一种产品时,使用工厂方法模式 - 需要创建一系列相关产品时,使用抽象工厂模式 4. **配置化** - 考虑使用配置文件来选择具体工厂 - 便于在运行时切换产品族 ## 与其他模式的关系 1. **工厂方法模式** - 抽象工厂通常基于一组工厂方法实现 - 抽象工厂关注产品族,工厂方法关注单个产品 2. **单例模式** - 抽象工厂可以结合单例模式使用 - 确保每个具体工厂只有一个实例 3. **建造者模式** - 当产品有复杂的内部结构时,可以结合建造者模式 - 抽象工厂负责创建产品族,建造者负责创建复杂对象