简单工厂、工厂方法、抽象工厂到底有什么区别?一文讲透工厂模式的演进

发布时间:2026/10/2 12:33:32

简单工厂、工厂方法、抽象工厂到底有什么区别?一文讲透工厂模式的演进 引言很多初学者分不清简单工厂、工厂方法、抽象工厂其实它们并不是三个孤立的设计模式而是同一条演进路线简单工厂 → 工厂方法 → 抽象工厂。简单工厂把创建逻辑抽离却堆满 if-else工厂方法把工厂也抽象掉新增产品不改老代码抽象工厂则解决一族产品的配套创建问题。每一步升级都是用更高复杂度换取更强扩展性。目录一. 简单工厂二. 工厂方法三. 抽象工厂实战软考真题一. 简单工厂1. 结构图2. 代码实现①创建抽象类、具体类abstract class Product{ public abstract void info(); } class ProductA extends Product{ Override public void info() { System.out.println(产品的信息A); } } class ProductB extends Product{ Override public void info() { System.out.println(产品的信息B); } }②创建工厂类class Factory{ public static Product createProduct(String type){ Product product null; switch (type){ case A: product new ProductA(); break; case B: product new ProductB(); break; default: System.out.println(没有 type 类型的产品); break; } return product; } }测试一下//简单工厂模式 public class SimpleFactory { public static void main(String[] args) { Product productA Factory.createProduct(A); productA.info(); Product productB Factory.createProduct(B); productB.info(); Product productC Factory.createProduct(C); productC.info(); } }运行结果如下3. 解读序号精髓点说明代码体现1返回类型是抽象类实际值是具体类编译期类型为父类型运行期类型为子类本质是多态向上转型public static Product createProduct(...)返回Product实际new ProductA()2父 子多态思想客户端只依赖抽象Product不依赖任何具体产品类Product productA Factory.createProduct(A);3封装创建客户端不再 newnew被关进工厂客户端与具体类解耦客户端只写Factory.createProduct(A)不出现new ProductA()4集中判断switch/if-else工厂内部集中决定创建哪个产品一目了然switch(type){ case A: ... case B: ... }5静态方法调用方便不用先创建工厂对象直接类名调用public static Product createProduct(...)6客户端只认“能干什么”不认“是谁”客户端只调抽象方法具体执行哪个由运行时对象决定productA.info();只调抽象方法7switch 是特征也是软肋新增产品要改 switch违反开闭原则这正是被工厂方法取代的原因每加一个产品就要加一个case8静态方法无法被继承重写简单直接但工厂无法扩展这是“简单”的代价static方法不能被 override4. 最大的缺点违反“开放—封闭”原则现在我们的工厂类只支持创建A、B两种产品但是后续加入产品C时遇到如下问题说白了此时我们由于新加了一个产品C导致不得不修改工厂类的代码。这的确违反了“开放—封闭”原则。因为我们通常对扩展是开放的对修改是关闭的。对应到此处就是你扩展了产品C是没问题的但是不能修改工厂类的代码。由于简单工厂模式存在上述缺陷因此引出下面的工厂方法模式.二. 工厂方法1. 结构图2. 代码实现①创建产品接口、实现类interface Product{ public void info(); } class ProductA implements Product{ Override public void info() { System.out.println(产品的信息A); } } class ProductB implements Product{ Override public void info() { System.out.println(产品的信息B); } }②创建工厂接口、实现类interface Factory{ public Product createProduct(); } class FactoryA implements Factory{ Override public Product createProduct() { return new ProductA(); } } class FactoryB implements Factory{ Override public Product createProduct() { return new ProductB(); } }测试一下//工厂方法 public class test { public static void main(String[] args) { Factory factoryA new FactoryA(); Product productA factoryA.createProduct(); productA.info(); Factory factoryB new FactoryB(); Product productB factoryB.createProduct(); productB.info(); } }运行效果3. 解读序号要点说明代码体现1工厂也抽象成接口工厂不再是一个具体类而是一个接口定义创建产品的规范interface Factory { Product createProduct(); }2每个产品配一个专属工厂一个具体产品对应一个具体工厂职责单一FactoryA→ProductAFactoryB→ProductB3返回类型是抽象产品实际值是具体产品和简单工厂一样编译期是父类型运行期是子类本质是多态public Product createProduct()返回Product实际new ProductA()4父 子多态思想客户端只依赖Product和Factory两个抽象不依赖具体类Product productA factoryA.createProduct();5客户端不再 switch 判断简单工厂的 switch 被“多态分发”取代选哪个工厂由客户端决定客户端选new FactoryA()还是new FactoryB()6新增产品不改老代码加一个产品 加一个产品类 加一个工厂类符合开闭原则新增ProductC只需加ProductCFactoryC7代价类数量翻倍每个产品都要配一个工厂类的数量成对增长N 个产品 → N 个产品类 N 个工厂类8只解决“一个产品等级”工厂接口里只有一个createProduct()搞不定产品族无法保证“按钮复选框”配套创建4. 优点遵循“开放—封闭”原则举例我们新加一个产品C只需要增加一个对应的专属工厂类即可而无需修改任何之前的代码也就是对拓展开放对修改关闭可见我们新增一个产品时只需要新增对应的类、具体工厂类即可而无需修改之前的任何代码这就遵守了“开放—封闭”原则即对新增开放对修改关闭。说白了就是当新增一部分功能时可以新增代码但尽量不要修改之前的代码。5. 补充这个结构图其实和上面的结构图是一个意思只不过画的方式有区别但表达的意思是一样的。下面的事项看看就行了解即可。三. 抽象工厂1. 结构图2. 代码实现// 抽象产品族 // 产品等级 1按钮 interface Button { void render(); } // 产品等级 2复选框 interface Checkbox { void render(); } // 具体产品Windows 家族 class WindowsButton implements Button { Override public void render() { System.out.println(渲染 Windows 按钮); } } class WindowsCheckbox implements Checkbox { Override public void render() { System.out.println(渲染 Windows 复选框); } } // 具体产品Mac 家族 class MacButton implements Button { Override public void render() { System.out.println(渲染 Mac 按钮); } } class MacCheckbox implements Checkbox { Override public void render() { System.out.println(渲染 Mac 复选框); } } // 抽象工厂定义一族产品的创建接口 interface GUIFactory { Button createButton(); Checkbox createCheckbox(); } // 具体工厂Windows 工厂 class WindowsFactory implements GUIFactory { Override public Button createButton() { return new WindowsButton(); } Override public Checkbox createCheckbox() { return new WindowsCheckbox(); } } // 具体工厂Mac 工厂 class MacFactory implements GUIFactory { Override public Button createButton() { return new MacButton(); } Override public Checkbox createCheckbox() { return new MacCheckbox(); } } // 客户端 public class AbstractFactoryTest { public static void main(String[] args) { // 只选一次工厂之后创建的所有组件都自动配套 GUIFactory factory new WindowsFactory(); // GUIFactory factory new MacFactory(); // 换一行就切换整个产品族 Button button factory.createButton(); Checkbox checkbox factory.createCheckbox(); button.render(); checkbox.render(); } }3. 解读序号优点说明代码体现1保证产品族内的一致性同一个工厂创建出的产品天然配套不会出现“Windows 按钮配 Mac 复选框”WindowsFactory只会产出WindowsButtonWindowsCheckbox2客户端与具体产品解耦客户端只依赖抽象Button、Checkbox、GUIFactory不碰任何具体类客户端代码里没有new WindowsButton()3切换产品族非常方便换一个工厂整个产品族一起换只改一行new WindowsFactory()→new MacFactory()4符合开闭原则对新增产品族而言新增一个产品族如 Linux 风格只需加一套产品类 一个工厂类不改老代码新增LinuxButton、LinuxCheckbox、LinuxFactory5职责清晰符合单一职责每个具体工厂只负责创建自己那一族产品MacFactory只造 Mac 系列6便于统一管理与扩展一族产品的创建逻辑集中在一个工厂里规范统一所有 Mac 组件的创建都归MacFactory4. 优点抽象工厂最大的优点保证一族产品配套一致且切换产品族只需换一个工厂。5. 补充实战软考真题题目以上就是本篇文章的全部内容喜欢的话可以留个免费的关注呦~~~
延伸阅读

更多相关文章

2026/10/2 12:28:32

VSCode 常用插件总结:用 TaoToken 统一管理 AI 编程助手配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/2 13:58:37

Token命中率:LLM推理的“隐形加速器”

一、Token命中率到底是什么?1.1 从KV Cache说起LLM以自回归方式生成文本:每生成一个新Token,都需要“回头看”前面所有Token的Key和Value张量来计算注意力。如果每次生成都重新计算全部历史Token的K/V,计算量会随序列长度线性增长…

2026/10/2 13:58:37

(132页PPT)精益生产现场管理和改善(附下载方式)

篇幅所限,本文只提供部分资料内容,完整资料请看下面链接 https://download.csdn.net/download/AI_data_cloud/88338604 资料解读:精益生产现场管理和改善 详细资料请看本解读文章的最后内容。 这份精益生产现场管理与改善的专业资料&#…

2026/10/2 13:53:36

【第2 章】WorkBuddy 从入门到高手

WorkBuddy 从入门到高手(第 2章):核心能力,办公六件套全拆解(超详细案例版) 这是一套面向「完全没用过 WorkBuddy」读者的系统学习路线,总共 7 章。本文是第 3 章。 系列目录:第 0 章…

2026/10/2 8:16:46

东莞市品牌网站建设报价常见报错与解决

东莞品牌网站建设报价单背后:一份保姆级建站教程避坑实录 网站做好了没人访问,这大概是很多老板最头疼的事。花了大几万做的品牌站,上线后流量惨淡,比路边摊还冷清。别急着骂外包公司,很多“东莞品牌网站建设报价”里藏着不少猫腻,比如用模板站冒充定制…

2026/10/1 17:09:46

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/10/1 10:48:55

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/10/2 0:02:57

PWN入门:从栈溢出原理到ROP链实战

1. 这不是“学PWN”,是重新理解你每天敲的每一行C代码我第一次在CTF赛场上写出能控制程序流的exp时,手抖得连gdb的c命令都输错三次。那道题只有23行C代码,一个gets()调用,一个printf(),一个return——它甚至没开NX&…

2026/10/2 0:02:57

Windows下cudaMallocHost显存占用之谜:WDDM与TCC模式差异及优化方案

1. 一个反直觉的显存占用现象第一次在 Windows 上看到cudaMallocHost把显存吃掉的时候,我的反应是打开任务管理器反复确认了三遍。明明调用的是主机端锁页内存分配,按 CUDA 文档的说法,这块内存应该落在系统 RAM 里,跟 GPU 的显存…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑