小张的工厂进化史——工厂模式
小张的工厂进化史——工厂模式
- 一、简单工厂模式:全能生产线
- 二、工厂方法模式:分品牌代工
- 三、抽象工厂模式:生态产品族
- 四、三种模式核心对比表
- 五、结合Spring实现简单工厂(实践)

小张从华强北起家,最初只有一条组装线,根据订单参数(手机/平板)手动切换生产流程。随着订单量激增,他经历了三次产业升级:
- 阶段1:全能生产线通过指令切换产品(简单工厂模式)
- 阶段2:引入代工厂分品牌生产(工厂方法模式)
- 阶段3:打造生态产品族统一管理(抽象工厂模式)
一、简单工厂模式:全能生产线
场景:小张初期用一条生产线,通过参数指令生产不同电子产品。
代码示例:
// 抽象产品:电子设备接口
public interface Device {void boot();
}// 具体产品:手机
public class Phone implements Device {@Overridepublic void boot() { System.out.println("【简单工厂】手机开机:Android系统启动");}
}// 具体产品:平板
public class Tablet implements Device {@Overridepublic void boot() { System.out.println("【简单工厂】平板开机:Android系统启动");}
}// 简单工厂类
public class ElectronicsFactory {public static Device createDevice(String type) {if ("phone".equalsIgnoreCase(type)) {return new Phone();} else if ("tablet".equalsIgnoreCase(type)) {return new Tablet();}throw new IllegalArgumentException("不支持的设备类型");}
}// 客户端调用
public class Client {public static void main(String[] args) {Device phone = ElectronicsFactory.createDevice("phone");phone.boot(); // 输出:手机开机...}
}
特点:
- 参数化创建:通过
if-else判断生产设备,违反开闭原则(新增产品需修改工厂类) - 适用场景:初期产品线单一(如仅手机和平板)
二、工厂方法模式:分品牌代工
场景:小张引入华为、小米代工厂,各品牌独立生产设备。
代码示例:
// 抽象工厂接口
public interface DeviceFactory {Device createDevice();
}// 具体工厂:华为代工厂
public class HuaweiFactory implements DeviceFactory {@Overridepublic Device createDevice() {return new HuaweiPhone(); // 华为手机}
}// 具体产品:华为手机
public class HuaweiPhone implements Device {@Overridepublic void boot() {System.out.println("【工厂方法】华为手机:HarmonyOS启动");}
}// 客户端调用
public class Client {public static void main(String[] args) {DeviceFactory factory = new HuaweiFactory();Device phone = factory.createDevice();phone.boot(); // 输出:华为手机...}
}
特点:
- 多态扩展:新增品牌(如OPPO)只需添加新工厂类,符合开闭原则
- 类爆炸:每新增一个品牌需增加2个类(工厂+产品)
三、抽象工厂模式:生态产品族
场景:小张扩展生态链,生产同一品牌的多类产品(手机+耳机),确保设计兼容。
代码示例:
// 抽象工厂接口
public interface BrandFactory {Phone createPhone();Earphones createEarphones();
}// 具体工厂:苹果生态
public class AppleFactory implements BrandFactory {@Overridepublic Phone createPhone() {return new iPhone(); // 苹果手机}@Overridepublic Earphones createEarphones() {return new AirPods(); // 苹果耳机}
}// 关联产品族
public class iPhone implements Phone {@Overridepublic void boot() {System.out.println("【抽象工厂】iPhone开机:iOS启动");}
}
public class AirPods implements Earphones {public void connect() {System.out.println("【抽象工厂】AirPods自动配对");}
}// 客户端调用
public class Client {public static void main(String[] args) {BrandFactory factory = new AppleFactory();factory.createPhone().boot(); // 输出:iPhone开机...factory.createEarphones().connect(); // 输出:AirPods自动配对...}
}
特点:
- 产品族兼容:确保同一品牌风格统一(如苹果极简设计)
- 接口膨胀:新增品牌需实现全套接口(如华为生态需实现createPhone()和createEarphones())
四、三种模式核心对比表
| 简单工厂模式 | 工厂方法模式 | 抽象工厂模式 | |
|---|---|---|---|
| 核心目标 | 快速生产单一产品 | 分品牌灵活扩展 | 创建兼容的生态产品族 |
| 扩展性 | ❌ 差(需修改代码) | ✅ 优(新增工厂类) | ❌ 差(需实现全套接口) |
| 类复杂度 | 1工厂类 + N产品类 | N工厂类 + N产品类 | M工厂类 + M×N产品类 |
| 设计原则 | 违反开闭原则 | 符合开闭原则 | 符合接口隔离原则 |
| 适用场景 | 初期单一产线(手机/平板) | 多品牌代工(华为/小米) | 生态链产品(苹果手机+耳机) |
五、结合Spring实现简单工厂(实践)
详细内容可参考:【当模板方法模式遇上工厂模式:一道优雅的烹饪架构设计】
抽象类(或者 接口)
public abstract class AbstractCooking {protected CookEnum cookEnum;protected abstract void aromaBlasting();}
枚举类
/*** 菜品枚举类*/
public enum CookEnum {KUNG_PAO_CHICKEN("kungPaoChicken", "宫保鸡丁"),MAPO_TO_FU("mapoTofu", "麻婆豆腐");private final String code;private final String name;CookEnum(String code, String name) {this.code = code;this.name = name;}....
}
宫保鸡丁
/*** 宫保鸡丁*/
@Service
public class KungPaoChicken extends AbstractCooking {public KungPaoChicken() {this.cookEnum = CookEnum.KUNG_PAO_CHICKEN;}@Overrideprotected void aromaBlasting() {System.out.println("葱姜蒜爆香");}
}
麻婆豆腐
/*** 麻婆豆腐*/
@Service
public class MapoTofu extends AbstractCooking {public MapoTofu() {this.cookEnum = CookEnum.MAPO_TO_FU;}@Overrideprotected void aromaBlasting() {System.out.println("煸炒郫县豆瓣酱+花椒粒");}
}
工厂类
@Service
public class CookFactory implements InitializingBean {// Spring启动时,会依赖注入 所有的AbstractCooking的bean,注入到cookings@Autowiredprivate List<AbstractCooking> cookings;// 定义Map存储 bean的映射关系private Map<CookEnum, AbstractCooking> cookingMap = new HashMap<>();public AbstractCooking getCookingByCode(String code) {CookEnum cookEnum = CookEnum.getByCode(code);return cookingMap.get(cookEnum);}// CookFactory的bean对象在初始化阶段,动态把 AbstractCooking的所有bean 设置到cookingMap (动态扩展的关键)@Overridepublic void afterPropertiesSet() throws Exception {for (AbstractCooking cooking: cookings) {cookingMap.put(cooking.getCookEnum(), cooking);}}
}
相关文章:
小张的工厂进化史——工厂模式
小张的工厂进化史——工厂模式 一、简单工厂模式:全能生产线二、工厂方法模式:分品牌代工三、抽象工厂模式:生态产品族四、三种模式核心对比表五、结合Spring实现简单工厂(实践) 小张从华强北起家,最初只有…...
AIP-217 不可达资源
编号217原文链接AIP-217: Unreachable resources状态批准创建日期2019-08-26更新日期2019-08-26 有时,用户可能会请求一系列资源,而其中某些资源暂时不可用。最典型的场景是跨集合读。例如用户可能请求返回多个上级位置的资源,但其中某个位置…...
C语言,原码、补码、反码
计算机是以补码来存储的 原码:正数最高位为:0;负数最高位为:1 (最高位是符号位) 正数:三码合一 如:2: 原码:0000 0000 0000 0000 0000 0000 0000 0010&#…...
2025年智能合约玩法创新白皮书:九大核心模块与收益模型重构Web3经济范式
——从国库管理到动态激励的加密生态全栈解决方案 一、核心智能合约架构解析 1. 国库合约:生态财政中枢 作为协议的金库守卫者,国库合约通过多签冷钱包与跨链资产池实现资金沉淀。其创新点包括: 储备资产动态再平衡:采用预言机实…...
【Android】Android 打包 Release 崩溃问题全解析:Lint 错误、混淆类丢失及解决方法大全
摘要: 在 Android 项目的 Release 打包过程中,经常遇到诸如 Lint 校验失败、程序闪退、类找不到等问题。本文将详细分析 Android 打包时常见的崩溃原因,特别是如何应对 Lint 报错、混淆引发的类丢失(NoClassDefFoundError…...
C++ Cereal序列化库的使用
C Cereal 库使用指南 Cereal 是一个轻量级的 C 序列化库,用于将对象序列化为二进制、XML 或 JSON 格式,以及从这些格式反序列化。它支持标准库类型和用户自定义类型的序列化,且无需修改原有类定义。 基本用法 1. 安装与包含 #include <…...
热门面试题第15天|最大二叉树 合并二叉树 验证二叉搜索树 二叉搜索树中的搜索
654.最大二叉树 力扣题目地址(opens new window) 给定一个不含重复元素的整数数组。一个以此数组构建的最大二叉树定义如下: 二叉树的根是数组中的最大元素。左子树是通过数组中最大值左边部分构造出的最大二叉树。右子树是通过数组中最大值右边部分构造出的最大…...
如何查看linux history命令文件
在Linux系统中,history命令用于显示用户在终端会话中执行过的命令历史。默认情况下,这些命令被保存在用户的家目录下的一个隐藏文件中,通常是.bash_history(对于bash shell)或.zsh_history(对于zsh shell&a…...
css易混淆的知识点
子选择器 (>) vs 后代选择器 (空格) 子选择器 (>) 只匹配直接子元素。后代选择器 (空格) 匹配所有后代元素(无论嵌套多深)。 绝对定位vs相对定位 布局: justify-content 的作用 控制子元素在主轴上的分布方式。常见值包括 flex-start、…...
Java对接智能客服:从0到1构建高并发对话系统的实战指南
引言:智能客服的进化与Java生态的融合 在数字化转型浪潮中,智能客服系统已成为企业服务升级的标配。当传统规则引擎逐步让位于NLP大模型,Java开发者如何构建高效稳定的对话系统?本文将结合阿里云通义千问、百度文心等最新AI能力&…...
【前缀和】矩阵区域和(medium)
矩阵区域和(medium) 题⽬描述:解法:代码Java 算法代码:C 算法代码: 题⽬描述: 题⽬链接:1314. 矩阵区域和 给你⼀个 m x n 的矩阵 mat 和⼀个整数 k ,请你返回⼀个矩阵 …...
5分钟用Docker Desktop新功能搭建Python+AI开发环境
Docker Desktop 4.25版本通过预置AI开发模板与零配置GPU支持,彻底简化PythonAI环境搭建流程。无需手动安装CUDA、无需配置虚拟环境,3条命令完成从零到模型训练的完整工作流。 一、Docker Desktop新功能核心价值 1.1 预置AI开发镜像库 • 开箱即用的深度…...
一周学会Pandas2 Python数据处理与分析-Pandas2读取Excel
锋哥原创的Pandas2 Python数据处理与分析 视频教程: 2025版 Pandas2 Python数据处理与分析 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili Excel格式文件是办公使用和处理最多的文件格式之一,相比CSV文件,Excel是有样式的。Pandas2提…...
BERT-DDP
DDP 代码执行流程详解 这份代码执行的是一个典型的数据并行分布式训练流程,利用多个 GPU(可能分布在多个节点上)来加速模型训练。核心思想是每个 GPU 处理一部分数据,计算梯度,然后同步梯度并更新模型。 假设你使用 …...
【MySQL】002.MySQL数据库基础
文章目录 数据库基础1.1 什么是数据库1.2 基本使用创建数据库创建数据表表中插入数据查询表中的数据 1.3 主流数据库1.4 服务器,数据库,表关系1.5 MySQL架构1.6 SQL分类1.7 存储引擎1.7.1 存储引擎1.7.2 查看存储引擎1.7.3 存储引擎对比 前言:…...
02-redis-源码下载
1、进入到官网 redis官网地址https://redis.io/ 2 进入到download页面 官网页面往最底下滑动,找到如下页面 点击【download】跳转如下页面,直接访问:【https://redis.io/downloads/#stack】到如下页面 3 找到对应版本的源码 https…...
大模型上下文协议MCP详解(1)—技术架构与核心机制
版权声明 本文原创作者:谷哥的小弟作者博客地址:http://blog.csdn.net/lfdfhl1. MCP概述 1.1 定义与目标 MCP(Model Context Protocol,模型上下文协议)是由Anthropic公司于2024年11月推出的开放标准协议。它旨在解决AI大模型与外部工具、数据源及API之间的标准化交互问题…...
Windows下安装depot_tools
一、引言 Chromium和Chromium OS使用名为depot_tools的脚本包来管理检出和审查代码。depot_tools工具集包括gclient、gcl、git-cl、repo等。它也是WebRTC开发者所需的工具集,用于构建和管理WebRTC项目。本文介绍Windows系统下安装depot_tools的方法。 二、下载depo…...
解决 vite.config.ts 引入scss 预处理报错
版本号: "sass": "^1.86.3","sass-loader": "^16.0.5","vite": "^6.2.0" 报错1:[plugin:vite:css] [SASS] Error:Cant find stylesheet to import vite.config.ts 开始文件错…...
MySQL学习笔记7【InnoDB】
Innodb 1. 架构 1.1 内存部分 buffer pool 缓冲池是主存中的第一个区域,里面可以缓存磁盘上经常操作的真实数据,在执行增删查改操作时,先操作缓冲池中的数据,然后以一定频率刷新到磁盘,这样操作明显提升了速度。 …...
分布式锁和事务注解结合使用
在分布式系统中,事务注解(如 Transactional)与分布式锁的结合使用是保障数据一致性和高并发安全的核心手段。以下是两者的协同使用场景及技术实现要点: 一、事务注解的局限性及分布式锁的互补性 维度事务注解(Transac…...
全国产压力传感器常见的故障有哪些?
全国产压力传感器常见的故障如哪些呢?来和武汉利又德的小编一起了解一下,主要包括以下几类: 零点漂移 表现:在没有施加压力或处于初始状态时,传感器的输出值偏离了设定的零点。例如,压力为零时,…...
使用nhdeep档案目录打印工具生成干部人事档案目录打印文件
打开nhdeep档案目录打印工具,在左侧的模版列表中选中"干部人事档案目录"模版。 然后点击右下角“批量导入行”按钮,选择事先准备好的人事目录数据excel文件完成导入。 人事目录数据excel文件的结构和内容如下: 导入完成后…...
工作记录 2015-08-24
工作记录 2015-08-24 序号 工作 相关人员 1 更新76.19的D:\FNEHRRD,更新的差不多了,还在测试中。具体情况见附件。 郝 识别引擎监控 Ps (iCDA LOG :剔除了204篇ASG_BLANK之后的结果): LOG_File 20150823.txt BLANK_CDA/ALL 102/947 (10.8%) TIME…...
在 Dev-C++中编译运行GUI 程序介绍(三)有趣示例一组
在 Dev-C中编译运行GUI程序介绍(三)有趣示例一组 前期见 在 Dev-C中编译运行GUI 程序介绍(一)基础 https://blog.csdn.net/cnds123/article/details/147019078 在 Dev-C中编译运行GUI 程序介绍(二)示例&a…...
Compose 适配 - 响应式排版 自适应布局
一、概念 基于可用空间而非设备类型来设计自适应布局,实现设备无关性和动态适配性,避免硬编码,以不同形态布局更好的展示内容。 二、区分可用空间 WindowSizeClasses 传统根据屏幕大小和方向做适配的方式已不再适用,APP的显示方式…...
光储充智能协调控制系统的设计与应用研究
摘要 随着化石能源枯竭与环境污染问题加剧,构建高效、稳定的新能源系统成为能源转型的关键。本文针对光伏发电间歇性、储能系统充放电效率及充电桩动态负荷分配等技术挑战,提出一种基于智能协调管理的光储充一体化解决方案。通过多源数据融合与优化控制算…...
UE4 踩坑记录
1、Using git status to determine working set for adaptive non-unity build 我删除了一个没用的资源,结果就报这个错,原因就是这条命令导致的, 如果这个项目是git项目, ue编译时会优先通过 git status检查哪些文件被修改&#…...
C语言超详细指针知识(一)
通过前面一段学习C语言的学习,我们了解了数组,函数,操作符等相关知识,今天我们将要进行指针学习,这是C语言中较难的一个部分,我将带你由浅入深慢慢学习。 1.内存与地址 在正式学习指针前,我们首…...
《算法笔记》3.3小节——入门模拟->图形输出
1036 跟奥巴马一起编程 #include <iostream> #include <cmath> using namespace std;int main() {int n,m;char c;cin>>n>>c;for (int i 0; i < n; i) {cout<<c;}cout<<endl;m round(1.0*n/2)-2;//round里面不能直接写n/2,…...
