当前位置: 首页 > news >正文

【设计模式】创建型设计模式之 工厂模式

一、介绍

工厂模式可以分为 3 个小类

  1. 简单工厂模式
  2. 工厂方法模式
  3. 抽象工厂模式

工厂模式的工厂类,并不一定以 Factory 结尾,例如 DataFormat、Calender 他们都是工厂类,通过静态方法来创建实例。

除此之外,创建对象的方法名称一般是 create+类名,但是也有其他的命名方式例如 getInstance()、createInstance() createInstance() ,甚至是 valueOf 也是工厂的方法例如 String 的 valueOf()方法。


二、简单工厂模式

介绍

image.png

  1. 将创建对象的函数,从代码中剥离并且将其放到一个独立的类中。让这个类只负责对象的创建。那这个类就是简单工厂模式的工厂类。
  2. 虽然大部分的工厂模式的结尾都是 Factory,但是不是必须的,例如 Java 中的 DateFormat、Calender 尽管没有以 Factory 但是他们也是工厂类。甚至 String.valueOf 也是工厂类。

自定义案例代码

// 定义 Shape 接口
interface Shape {void draw();
}// 具体形状类:圆形
class Circle implements Shape {@Overridepublic void draw() {System.out.println("Inside Circle::draw() method.");}
}// 具体形状类:矩形
class Rectangle implements Shape {@Overridepublic void draw() {System.out.println("Inside Rectangle::draw() method.");}
}// 简单工厂类,用于创建形状对象
class ShapeFactory {// 使用 getShape 方法获取形状类型的对象public static Shape getShape(String shapeType) {if (shapeType == null) {return null;} else if (shapeType.equalsIgnoreCase("CIRCLE")) {return new Circle();} else if (shapeType.equalsIgnoreCase("RECTANGLE")) {return new Rectangle();}return null;}
}// 客户端代码
public class SimpleFactoryPatternDemo {public static void main(String[] args) {// 获取形状类型的对象Shape shape1 = ShapeFactory.getShape("CIRCLE");// 调用 Circle 的 draw 方法shape1.draw();Shape shape2 = ShapeFactory.getShape("RECTANGLE");// 调用 Rectangle 的 draw 方法shape2.draw();// 请求一个不支持的形状类型Shape shape3 = ShapeFactory.getShape("SQUARE");if (shape3 != null) {shape3.draw();} else {System.out.println("Shape not supported.");}}
}

第二类简单工厂

如果将简单工厂模式和类似的单例模式组合起来,那么可以称之为第二类简单工厂模式

public class ReleConfigParseFactory{private static final Map<String,RuleConfigParse> rulesMap=new HashMap<>();static{rulesMap.put(XXXX)}public static getParse(String name){return relesMap.get(name);}
}



三、工厂方法模式

  1. 简单工厂模式如果要新增产品类型则需要在工厂类中新增 不够符合开闭原则
  2. 工厂方法模式 对于新增一个具体的产品来说,只需要新增一个工厂类更符合开闭原则。
  3. 在业务中创建工厂类仍然负责,所以可以结合简单工厂。对于具体的 FactoryABC 再创建一个简单工厂也就是工厂的工厂。这样新增工厂类后,只需要在工厂的工厂中添加该工厂而不需要大量的改动。

缺点:

  1. 工厂类只包含一个创建代码,功能单薄有点过度设计。如果代码足够简单,应该使用简单工厂模式。



四、抽象工厂模式


如果具体需要创建的对象包含多种分类,那么实用工厂方法模式可能会产生大量的工厂类。
例如上图,包含两种产品 Computer 和 Phone ,同事包含两个厂商 小米和苹果,如果使用工厂方法则会产生四个工厂。
引入抽象工厂模式后,AppleFactory 和 MiFactory 每个工厂负责多种类型的产品可以有效减少对应工厂的个数。



五、总结

使用工厂模式的场景

场景 1:代码中存在根据不同条件创建不同对象的代码,可以考虑使用工厂模式将这一大段代码进行抽离。如果每个对象的创建都比较简单那么就使用简单工厂模式,如果对象的创建过程比较负责责使用工厂方法模式将每个对象的创建过程封装到各自的工厂类中。
**场景 2:**一个类的对象创建比较复杂,例如涉及其他的对象,复杂的初始化逻辑等。也可以考虑使用工厂模式,将对象创建的过程封装到工厂模式中。
工厂模式作用总结:

可以根据下面四条规则判断是否使用工厂模式

  1. 封装变化 利用工厂模式封装创建逻辑,创建逻辑的变更对调用者透明。
  2. 代码复用 避免业务中创建对象的代码散落各处,避免重复编写。
  3. 隔离复杂性:封装复杂的创建逻辑,让使用者无需关注具体的创建细节。
  4. 控制复杂度:将创建逻辑与使用逻辑分离,简化代码。

开发中常见的工厂模式案例

  1. DateFormat、Calendar 类
  2. 日志工厂 LoggerFactory 经常使用工厂模式来创建日志记录器(Logger)实例。开发者可以通过工厂方法请求一个日志记录器,而不需要知道具体实现细节。这样可以在不修改应用程序代码的情况下,灵活切换日志框架。
  3. Spring 这种 DI 框架,例如 BeanFactory 管理着对象的声明周期,也作为对象的创建工厂

相关文章:

  • 我要成为算法高手-双指针篇
  • 34.打印K型
  • Vue10-事件修饰符
  • React@16.x(25)useReducer
  • orbslam2代码解读(4):loopclosing回环检测线程
  • 从票务到游戏:Celestia 首届黑客松亮点项目盘点
  • 笨蛋学算法之LeetCodeHot100_2_字母异位词分组(Java)
  • 【机器学习理论基础】定量变量和定性变量
  • 30岁迷茫?AI赛道,人生新起点
  • 【ArcGIS微课1000例】0115:字段数据类型案例详解
  • 计算广告读书杂记-待整理
  • 【AI大模型】Transformers大模型库(七):单机多卡推理之device_map
  • 基于SWIFT和Qwen1.5-14B-Chat进行大模型LoRA微调测试
  • 易舟云财务软件:数字化时代的财务管家
  • C/C++ 进阶(6)红黑树
  • 网络传输文件的问题
  • 【Leetcode】104. 二叉树的最大深度
  • 【译】理解JavaScript:new 关键字
  • 2019年如何成为全栈工程师?
  • cookie和session
  • CSS相对定位
  • isset在php5.6-和php7.0+的一些差异
  • Laravel Telescope:优雅的应用调试工具
  • Magento 1.x 中文订单打印乱码
  • Storybook 5.0正式发布:有史以来变化最大的版本\n
  • 程序员最讨厌的9句话,你可有补充?
  • 聊一聊前端的监控
  • 如何打造100亿SDK累计覆盖量的大数据系统
  • 小程序滚动组件,左边导航栏与右边内容联动效果实现
  • 智能情侣枕Pillow Talk,倾听彼此的心跳
  • ​如何防止网络攻击?
  • #HarmonyOS:Web组件的使用
  • #我与Java虚拟机的故事#连载07:我放弃了对JVM的进一步学习
  • $.ajax()参数及用法
  • (04)odoo视图操作
  • (2)STM32单片机上位机
  • (6)【Python/机器学习/深度学习】Machine-Learning模型与算法应用—使用Adaboost建模及工作环境下的数据分析整理
  • (delphi11最新学习资料) Object Pascal 学习笔记---第2章第五节(日期和时间)
  • (Demo分享)利用原生JavaScript-随机数-实现做一个烟花案例
  • (MATLAB)第五章-矩阵运算
  • (八)Flask之app.route装饰器函数的参数
  • (草履虫都可以看懂的)PyQt子窗口向主窗口传递参数,主窗口接收子窗口信号、参数。
  • (附源码)ssm基于jsp高校选课系统 毕业设计 291627
  • (五)网络优化与超参数选择--九五小庞
  • (转)程序员疫苗:代码注入
  • (转载)微软数据挖掘算法:Microsoft 时序算法(5)
  • .axf 转化 .bin文件 的方法
  • .net core 连接数据库,通过数据库生成Modell
  • .NET Core、DNX、DNU、DNVM、MVC6学习资料
  • .NET Standard / dotnet-core / net472 —— .NET 究竟应该如何大小写?
  • .net 流——流的类型体系简单介绍
  • .NET 直连SAP HANA数据库
  • .NET大文件上传知识整理
  • .NET精简框架的“无法找到资源程序集”异常释疑
  • .net开发时的诡异问题,button的onclick事件无效