3. 抽象工厂模式(Abstract Factory)
3. 抽象工厂模式(Abstract Factory)
问题:需要创建一整套相关对象(比如不同风格的 UI 组件)。
核心:在工厂方法的基础上再抽象一层,一个工厂负责生产一套产品。
interface Renderable {
render(): string;
}
interface UIFactory {
createButton(): Renderable;
createInput(): Renderable;
}
class LightFactory implements UIFactory {
createButton(): Renderable { return { render: () => '浅色按钮' }; }
createInput(): Renderable { return { render: () => '浅色输入框' }; }
}
class DarkFactory implements UIFactory {
createButton(): Renderable { return { render: () => '深色按钮' }; }
createInput(): Renderable { return { render: () => '深色输入框' }; }
}
type Theme = 'light' | 'dark';
function createUI(theme: Theme): UIFactory {
const factories: Record<Theme, new () => UIFactory> = {
light: LightFactory,
dark: DarkFactory,
};
return new factories[theme]();
}
const ui = createUI('dark');
console.log(ui.createButton().render()); // 深色按钮package abstractfactory
import "fmt"
type Button interface{ Render() string }
type Input interface{ Render() string }
type UIFactory interface {
CreateButton() Button
CreateInput() Input
}
// 浅色
type LightButton struct{}
func (b LightButton) Render() string { return "浅色按钮" }
type LightInput struct{}
func (i LightInput) Render() string { return "浅色输入框" }
type LightFactory struct{}
func (f LightFactory) CreateButton() Button { return LightButton{} }
func (f LightFactory) CreateInput() Input { return LightInput{} }
// 深色
type DarkButton struct{}
func (b DarkButton) Render() string { return "深色按钮" }
type DarkInput struct{}
func (i DarkInput) Render() string { return "深色输入框" }
type DarkFactory struct{}
func (f DarkFactory) CreateButton() Button { return DarkButton{} }
func (f DarkFactory) CreateInput() Input { return DarkInput{} }
func NewUIFactory(theme string) (UIFactory, error) {
switch theme {
case "light":
return LightFactory{}, nil
case "dark":
return DarkFactory{}, nil
default:
return nil, fmt.Errorf("未知主题: %s", theme)
}
}实战场景
- 多主题 UI 套件:浅色主题、深色主题、品牌主题各自产出一整套按钮、输入框、弹窗和卡片,确保视觉风格一致。
- 跨平台组件:Web、iOS、Android、桌面端都需要“按钮、菜单、对话框”这组组件,抽象工厂可以按平台返回同一族实现。
- 多数据库适配:不同数据库不只连接方式不同,查询构造器、事务管理器、迁移器也可能是一整套实现。
- 云厂商切换:对象存储、消息队列、函数计算、日志服务经常按 AWS、GCP、阿里云、Cloudflare 成套切换。
- 支付国家化:不同国家或地区的支付方式、税费计算、发票生成、退款流程是一组相关对象,适合由地区工厂统一创建。
- 游戏皮肤包:同一角色需要不同主题下的贴图、音效、粒子和 UI 资源,工厂返回一套风格一致的资源对象。
- 多租户定制:企业版 SaaS 里,不同租户可能有自己的审批器、权限策略、通知模板和报表导出器。
- 测试环境套件:集成测试时一次性替换 repository、queue、mailer、storage 为内存实现,避免真实外部依赖。
- 协议栈组合:HTTP、gRPC、WebSocket 的客户端、请求对象、响应解析器和错误映射通常需要成套出现。
- 设计系统迁移:旧设计系统和新设计系统并行时,用不同工厂提供同名组件,页面逐步切换而不直接依赖具体实现。