抽象工厂模式创建产品族工厂方法模式解决的是“一个产品等级结构”的创建问题。比如支付方式只有Payment一种产品接口每个具体工厂创建一个具体支付实现。但现实中有另一类场景系统需要创建一系列相关或相互依赖的对象而且这些对象必须成套使用。比如一个跨平台 UI 库Windows 风格下需要 Windows 按钮和 Windows 复选框Mac 风格下需要 Mac 按钮和 Mac 复选框。你不能在 Windows 风格里混用 Mac 复选框否则界面就乱了。这种“一系列相关对象”就是产品族。抽象工厂模式专门用来创建产品族。定义抽象工厂模式提供一个接口用于创建一系列相关或相互依赖的对象而无需指定它们具体的类。简单说工厂方法生产一个产品抽象工厂生产一套产品。结构抽象工厂模式包含五个角色抽象产品 A、B…定义同一产品族中不同产品的接口。具体产品 A1、B1…实现抽象产品属于同一个产品族。抽象工厂声明创建产品族中所有产品的方法。具体工厂实现抽象工厂创建同一个产品族的具体产品。客户端只依赖抽象工厂和抽象产品不接触具体类。代码示例跨平台 UI假设我们要开发一个跨平台 UI 库支持 Windows 和 Mac 两种风格。每种风格都有按钮和复选框。抽象产品 A按钮publicinterfaceButton{voidrender();}抽象产品 B复选框publicinterfaceCheckbox{voidcheck();}Windows 产品族publicclassWindowsButtonimplementsButton{Overridepublicvoidrender(){System.out.println(渲染 Windows 按钮);}}publicclassWindowsCheckboximplementsCheckbox{Overridepublicvoidcheck(){System.out.println(勾选 Windows 复选框);}}Mac 产品族publicclassMacButtonimplementsButton{Overridepublicvoidrender(){System.out.println(渲染 Mac 按钮);}}publicclassMacCheckboximplementsCheckbox{Overridepublicvoidcheck(){System.out.println(勾选 Mac 复选框);}}抽象工厂publicinterfaceGUIFactory{ButtoncreateButton();CheckboxcreateCheckbox();}具体工厂publicclassWindowsFactoryimplementsGUIFactory{OverridepublicButtoncreateButton(){returnnewWindowsButton();}OverridepublicCheckboxcreateCheckbox(){returnnewWindowsCheckbox();}}publicclassMacFactoryimplementsGUIFactory{OverridepublicButtoncreateButton(){returnnewMacButton();}OverridepublicCheckboxcreateCheckbox(){returnnewMacCheckbox();}}客户端publicclassApplication{privateButtonbutton;privateCheckboxcheckbox;publicApplication(GUIFactoryfactory){buttonfactory.createButton();checkboxfactory.createCheckbox();}publicvoidrender(){button.render();checkbox.check();}publicstaticvoidmain(String[]args){// 切换产品族只需换一个工厂GUIFactoryfactorynewWindowsFactory();ApplicationappnewApplication(factory);app.render();}}客户端只依赖GUIFactory、Button、Checkbox。要换成 Mac 风格只需要把WindowsFactory换成MacFactory其他代码一行不用改。与工厂方法的区别这是最容易混淆的地方。用一句话区分工厂方法一个抽象产品多个具体产品每个具体产品对应一个具体工厂。抽象工厂多个抽象产品多个产品族每个具体工厂负责创建一个产品族。对比维度工厂方法抽象工厂产品等级结构一个多个产品族无此概念有强调成套使用抽象工厂的方法数一个多个扩展方向新增产品容易新增产品族容易新增产品等级困难开闭原则对产品扩展开放对产品族扩展开放对产品等级修改关闭典型场景日志框架、支付方式跨平台 UI、数据库访问层抽象工厂的“开闭原则”是双向的新增一个产品族比如加 Linux 风格只需新增LinuxFactory和相关产品类不用改已有代码。✅新增一个产品等级比如加一个TextField需要修改GUIFactory接口和所有具体工厂。❌所以抽象工厂适合“产品族稳定、产品等级会扩展”的场景。如果产品等级经常变抽象工厂就不合适。另一个经典例子数据库访问层抽象工厂在数据库访问层非常常见。假设系统要支持 MySQL 和 Oracle每种数据库都有连接、命令、事务等对象。// 抽象产品publicinterfaceConnection{voidconnect();}publicinterfaceCommand{voidexecute(Stringsql);}// MySQL 产品族publicclassMySQLConnectionimplementsConnection{...}publicclassMySQLCommandimplementsCommand{...}// Oracle 产品族publicclassOracleConnectionimplementsConnection{...}publicclassOracleCommandimplementsCommand{...}// 抽象工厂publicinterfaceDatabaseFactory{ConnectioncreateConnection();CommandcreateCommand();}// 具体工厂publicclassMySQLFactoryimplementsDatabaseFactory{...}publicclassOracleFactoryimplementsDatabaseFactory{...}客户端通过DatabaseFactory创建连接和命令不关心底层是 MySQL 还是 Oracle。切换数据库时只需换一个工厂实现。优点保证产品族一致性。同一个工厂创建的产品天然属于同一个族不会出现 Windows 按钮配 Mac 复选框的情况。客户端与具体产品解耦。客户端只依赖抽象工厂和抽象产品具体类完全隐藏。符合开闭原则产品族维度。新增产品族时不需要修改已有代码。集中管理产品族。产品族的切换只需换一个具体工厂。缺点扩展产品等级困难。新增一个产品接口要修改抽象工厂和所有具体工厂违反开闭原则。抽象工厂接口庞大。产品族中产品越多抽象工厂的方法就越多接口会变得臃肿。类数量增加。每个产品族都要一套具体产品类和一个具体工厂类的数量增长很快。适用场景系统需要创建多个相关对象且它们必须成套使用。系统需要支持多种“风格”或“平台”且风格之间相互独立。客户端不关心具体产品类只依赖抽象接口。产品族相对稳定产品等级可能扩展。典型应用跨平台 UI 库Windows、Mac、Linux 风格。数据库访问层MySQL、Oracle、PostgreSQL。游戏中的不同种族人族、兽族、神族各有自己的建筑和兵种。不同主题的报表生成器。在 JDK 和 Spring 中的体现JDK 中的抽象工厂javax.xml.parsers.DocumentBuilderFactory是一个抽象工厂。它提供newDocumentBuilder()创建DocumentBuilder还提供newDocument()等创建相关对象。具体工厂由系统属性或服务提供者决定客户端不直接new。java.sql.Connection可以看作抽象工厂它提供createStatement()、prepareStatement()等方法返回同一数据库产品族中的命令对象。Spring 中的体现Spring 的BeanFactory体系可以看作抽象工厂。BeanFactory是抽象工厂XmlBeanFactory、AnnotationConfigApplicationContext是具体工厂它们负责创建整个应用所需的各种 Bean。客户端通过getBean()获取对象不关心创建细节。不过 Spring 的 BeanFactory 比经典抽象工厂更灵活它不限定产品族而是根据配置动态创建任意类型的 Bean。总结抽象工厂模式的核心是产品族。它把一组相关对象的创建集中到一个工厂接口中保证客户端拿到的是同一族的产品。工厂方法关注“一个产品的创建”抽象工厂关注“一族产品的创建”。选择哪种工厂模式取决于你的产品结构只有一个产品等级且需要扩展产品 → 工厂方法。有多个产品等级需要成套创建 → 抽象工厂。产品很少且稳定 → 简单工厂。理解产品族和产品等级这两个概念就能准确判断什么时候该用抽象工厂。
企业数字化 ERP 产品动态
相关推荐
熬夜改论文?2026年TaoToken一键生成论文工具排行榜权威发布,轻松达标不是梦! /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 11:43:47
ax调度实战:Agentic编排与Kubernetes集成指南 1. 从"ax"这个标题说起:一个被低估的编排入口第一次看到"ax"这个标题,很多人会以为是某个命令行工具的缩写,或者某个内部项目的代号。但结合热搜词里的ax调度、agentic、orchestration、kubernetes、cli这几个关键词&… · 2026/9/26 11:43:47
LiteLLM 安装教程:用 TaoToken 统一 Key 打通多模型调用 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 11:43:34
JSP小区水电费管理系统毕设实战:从环境搭建到答辩避坑 简介:这是一套面向高校计算机相关专业毕业设计的JSP小区水电费管理系统完整项目包,采用JSPMySQLB/S架构,适合正在准备毕设或需要Java Web实战练手的同学参考。系统分为前台与后台两大模块:前台提供站内新闻浏览、在线留言与回复查… · 2026/9/26 12:26:38
Java五子棋网络对战毕设实战:Socket通信与多线程机制解析 简介:一份面向计算机专业毕业生的Java五子棋手机网络对战游戏完整毕设项目,包含可直接运行的软件源码与系统设计文档,适合用于课题研究、课程实践与论文参考。压缩包约5.55MB,以Java源码与论文文档为主,覆盖Java基础、… · 2026/9/26 12:26:38
基于JSP的小区水电费管理系统:从抄表到缴费全流程设计与实现 简介:这份资源是面向高校计算机相关专业学生与Java Web初学者的小区水电费管理系统毕业设计完整包,采用JSPMySQLB/S架构,可作为课程设计、毕业设计选题或JSP入门练手项目。压缩包共713个文件,约10.12MB,以gif图片、jsp… · 2026/9/26 12:26:38
MySQL read_only 命令全解:从主从切换到权限边界 我第一次把它写进主从切换预案,是在一个凌晨的变更窗口里。脚本依次执行 SET GLOBAL read_only ON; 、检查复制状态、然后把流量切到新主节点。当时根本没多想——就五个单词的 SQL,能有什么花头?直到第二天业务方拿着截图来找我ÿ… · 2026/9/26 12:26:38
MATLAB多源风场融合与低空航路优化实战 1. 这不是“又一篇MATLAB教程”,而是一次真实建模现场的复盘2025华为杯D题——低空湍流监测及最优航路规划,表面看是典型的“数学建模编程实现”组合题,但真正动手做过的人会立刻意识到:它根本不是考你能不能调用fmincon或画出一张… · 2026/9/26 12:26:38
2026国自然评审改革下,跨学科基金申请书如何打动多元评审专家? 每年国自然申报季,青年学者群里总少不了“本子写好了,方向太交叉怕被毙”“创新点很大,但评审专家背景太杂怎么讲”这类焦虑。2026年的评审改革,把这个矛盾又放大了整整一轮:分类评审更细、函评专家匹配更看重交叉学科… · 2026/9/26 12:26:31
数据库课后习题答案别硬背:当测试用例集刷,效率翻倍 简介:万常选版《数据库原理与设计》课后习题答案资源,覆盖第2至6章及第9章,适合正在学习关系模型、数据库建模、关系数据理论与模式求精的本科生、自学者作为复习与自测材料。压缩包共7个文件,含3个doc参考答案、2个sql示例脚本、… · 2026/9/26 0:00:21
OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 0:00:40
向下兼容与向上兼容:接口设计中的兼容性策略与工程实践 一次版本升级事故,是很多团队绕不过去的坎。线上环境里,服务端明明已经上线了新版接口,老的移动端还在照着旧文档传参数。请求一到网关,校验直接拒绝,用户操作失败,客服群炸了锅,开发群里开始互… · 2026/9/26 0:00:46