技术成神之路:设计模式(四)工厂方法模式

1.定义


工厂方法模式(Factory Method Pattern)是一种创建型设计模式,它提供了一种创建对象的接口,而不是通过具体类来实例化对象。工厂方法模式的主要作用是让子类决定实例化哪一个类,从而实现对象创建的延迟到具体子类中进行。

2.主要作用


作用就是使设计更加灵活和可扩展。通过这种方式,父类无需知道具体要创建的对象是哪一种,这样就提高了系统的可扩展性和可维护性(符合开闭原则)一切优秀的模式都向设计原则看齐。

3.解决的问题

说到解决的问题,这里就不得不提下简单工厂模式了,什么?你不知道简单工厂模式是什么,没关系,先来看下定义:

简单工厂模式是一种创建型模式,它定义了一个工厂类,该类包含一个方法,根据给定的参数来返回不同类的实例。
客户端通过向工厂类传递参数来获取所需的具体对象实例,而不需要直接实例化对象。

包含角色:

  1. 工厂类(Factory):负责根据客户端的请求创建相应的对象。

  2. 产品类(Product):被创建的对象的基类或接口。具体的产品类是工厂类所创建的对象类型。

  3. 具体产品类(Concrete Product):实现了产品接口的具体对象类,由工厂类根据客户端的需求创建和返回。

UML类图:
在这里插入图片描述
代码示例:

public class LoggerFactory {public static Logger createLogger(String logType) {if ("Console".equals(logType)) {return new ConsoleLogger();} else if ("File".equals(logType)) {return new FileLogger();} else if ("Remote".equals(logType)) {return new RemoteLogger();} else {throw new IllegalArgumentException("Unsupported log type");}}
}

通过 LoggerFactory.createLogger("Console")LoggerFactory.createLogger("File") 或者 LoggerFactory.createLogger("Remote") 来获取不同类型的日志记录器,这种方式就是简单工厂模式,熟不熟悉,在你的项目中是不是也使用过这种模式呢,由于不难理解所以称为简单

简单是简单,当然他也有一些弊端,如果上面示例代码中 Logger 抽象类中只有打印一个方法,后续需要新增保存日志,过滤日志… 问题就暴露出来了,简单来说就是 简单工厂模式违反了开闭原则,即对扩展开放,对修改关闭

工厂方法模式解决了简单工厂模式的哪些问题?

  • 开闭原则:工厂方法模式遵循开闭原则,通过定义抽象工厂类和具体工厂类的继承关系,新增产品时只需增加具体工厂类和产品类,而无需修改现有代码,降低了系统的耦合性。
  • 扩展性:工厂方法模式支持更多的灵活性,每个具体的工厂类只负责创建对应的产品,符合单一职责原则,代码更加清晰和可维护。
  • 维护性:由于工厂方法模式将对象的创建延迟到子类中,避免了简单工厂模式中工厂类集中所有产品创建逻辑的问题,使代码结构更加清晰和可扩展。

简单来说,就是解决了简单工厂模式中集中创建逻辑和不符合开闭原则的问题,提高了代码的灵活性和可维护性。

4.模式原理

包含角色:

  1. 产品(Product):定义产品的接口。
  2. 具体产品(ConcreteProduct):实现产品接口的具体类。
  3. 工厂(Factory):定义创建产品对象的接口。
  4. 具体工厂(ConcreteFactory):实现创建产品对象的具体类。

UML类图:
在这里插入图片描述

// 定义产品接口
public interface Product {String operation();
}// 定义具体产品类
public class ConcreteProductA implements Product {@Overridepublic String operation() {return "产品A";}
}public class ConcreteProductB implements Product {@Overridepublic String operation() {return "产品B";}
}// 定义工厂接口
public abstract class Creator {// 工厂方法public abstract Product factoryMethod();// 其它操作方法public String someOperation() {Product product = factoryMethod();return product.operation();}
}// 定义具体工厂类
public class ConcreteCreatorA extends Creator {@Overridepublic Product factoryMethod() {return new ConcreteProductA();}
}public class ConcreteCreatorB extends Creator {@Overridepublic Product factoryMethod() {return new ConcreteProductB();}
}// 客户端代码
public class Client {public static void main(String[] args) {clientCode(new ConcreteCreatorA());clientCode(new ConcreteCreatorB());}public static void clientCode(Creator creator) {System.out.println("Client: " + creator.someOperation());}
}

打印:

Client: 产品A
Client: 产品B

相较简单工厂模式 增加了一个具体工厂角色,每增加一个具体产品,需要同时增加一个具体工厂类。所以说各有优缺点吧。

4.优缺点


优点:

  • 遵循开闭原则:可以在引入新产品时不修改现有代码。
  • 遵循单一职责原则:将产品对象的创建逻辑封装在工厂类中。
  • 减少代码耦合:客户端不直接依赖于具体类,只依赖于抽象产品和工厂接口(符合依赖倒置原则)。.

缺点:

  • 增加代码复杂性:每增加一个具体产品,需要同时增加一个具体工厂类。
  • 类的数量增加:每个具体产品都需要一个对应的具体工厂,会导致类的数量增加。

5.应用场景


  1. 需要创建复杂对象:当对象的创建过程比较复杂,且需要多步操作时。
  2. 产品种类多且类型不确定:当系统中需要创建的产品种类较多且类型在运行时才确定时。
  3. 需要对创建过程进行控制:当需要对对象的创建过程进行控制,并且希望将控制逻辑封装起来时。

emm… 其实还是简单工厂模式 应用场景更广泛些,毕竟简单好用🤭

总结比较:

  • 简单工厂模式适合于对象类型较少且不经常变化的场景,代码较为简单,但不符合开闭原则,难以扩展新的产品类型。
  • 工厂方法模式更加符合开闭原则,通过增加新的具体工厂和具体产品类来扩展系统功能,但会增加系统中类的个数和复杂度。

6.总结


工厂模式解决了简单工厂模式中集中创建逻辑和不符合开闭原则的问题,但同时自身也有一些弊端,但通过合理应用工厂方法模式,在特定的场景可以有效地提高系统的可维护性和扩展性。

设计模式没有最好的,只有最适合的,大家在选用时,要权衡利弊,避免过度设计!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/43025.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024年6月国产数据库大事记-墨天轮

本文为墨天轮社区整理的2024年6月国产数据库大事件和重要产品发布消息。 目录 2024年6月国产数据库大事记 TOP102024年6月国产数据库大事记(时间线)产品/版本发布兼容认证代表厂商大事记厂商活动相关资料 2024年6月国产数据库大事记 TOP10 2024年6月国…

最优雅的PHP框架 Laravel

Laravel 之所以被称为最优雅的 PHP 框架,是因为它在设计和功能上做了很多独特的创新,极大地提高了开发效率和代码的可维护性。以下是 Laravel 受欢迎的主要原因: 良好的文档和社区支持 Laravel 有详尽的官方文档,涵盖了框架的所有功能和用法。此外,Laravel 社区非常活跃…

【Python】已解决:SyntaxError invalid syntax

文章目录 一、分析问题背景二、可能出错的原因三、错误代码示例四、正确代码示例五、注意事项 已解决:SyntaxError invalid syntax 一、分析问题背景 在Python编程中,SyntaxError: invalid syntax是一个常见的错误,它通常表示代码中存在语法…

.net开发:NPOI生成excel文件到磁盘

源码实测可用 使用.net工具包NPOI,生成excel文件到本地磁盘。 实际项目中可以指定路径到服务器,把生成的文件存放到服务器指定目录。 controller层 [HttpPost("ExportExcel")]public void ExportExcel(){_TestService.ExportToExcel();} serv…

redis中的事务和mysql中的事务有什么区别?

Redis和MySQL的事务在概念和特性上存在一些显著的区别: 1. 原子性(Atomicity): - MySQL:事务具有原子性,即事务中的所有操作要么全部成功,要么全部失败,如果中途出现错误,整个事…

Linux内核 -- 虚拟化之virtqueue结构

Linux Kernel中的Virtqueue Virtqueue是Linux Kernel中用于实现Virtio设备的一个关键数据结构。Virtio是一种虚拟I/O设备标准,旨在简化虚拟化环境中虚拟设备与虚拟机之间的通信。Virtqueue则是实现这种通信的核心机制。以下是Virtqueue的一些关键点: V…

主流I/O模型总结(Linux Windows)

I/O复用模型(EPOLL) 模型思想:向内核注册需要监听的文件描述符,操作系统负责保存监视对象文件描述符,当有事件发生时,epoll_wait仅返回有事件发生的文件描述符数组 优点: 1.无需编写以监视状态为目的的针对所有文件描述符的循环语…

案例|水上水下一体化测量,为九寨沟精准把脉

​ 九寨沟,被誉为“人间仙境”,其湖群以独特的地理位置和优美的自然景观吸引着世界各地的游客,更是九寨沟生态系统中不可或缺的重要组成部分。因此,精准地掌握湖群的地形数据、水体分布及变化情况,能够揭示水下生态系…

【数据结构与算法基础】算法复杂度

欢迎光顾我的homepage 前言 算法就是定义良好的计算过程,它取一个活一组的值输入,并产生出一个或一组值作为输出。简单来说,算法就是一系列的计算步骤,用来将输入数据转化成输出结果。 一、算法效率 如何去衡量一个算法的好坏&am…

[C++]——同步异步日志系统(3)

同步异步日志系统 一、日志系统框架设计1.1模块划分1.1.1 日志等级模块1.1.2 日志消息模块1.1.3 日志消息格式化模块1.1.4 日志落地模块(日志落地的方向是工厂模式)1.1.5 日志器模块(日志器的生成是建造者模式)1.1.6 异步线程模块…

Android12上实现双以太网卡共存同时访问外网

具体实现如下: 修改main 表优先级到9999, 作用:eth0 eth1 访问 不去teardown 低分数网线 diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java index 418e…

Ubuntu 22.04 设置swap交换空间

经常爆内存,导致很多应用没有办法一直正常运行,可以通过设置swap来缓解一下,虽然和内存的速度无法媲美,但是能一定程度缓解一下问题。 一、查看当前分区 查看当前系统的swap大小 free -m 二、关闭现有的swap分区 将/etc/fstab…

CUDA Kernel调试与优化--背景知识扫盲(LLM生成)

CUDA Kernel调试与优化–背景知识扫盲(LLM生成) 对于使用CUDA进行调试与性能优化,官方提供了丰富的参考资料和工具。以下是一些关键资源,可以帮助你更好地调试和优化CUDA代码: 官方文档和指南 CUDA Toolkit Documentation URL: CUDA Toolk…

强化学习总结(有具体代码实现)

文章目录 第一部分 强化学习基础第1章 强化学习概述1.1 强化学习概念1.2 强化学习的环境1.3 强化学习的目标1.4 强化学习的数据 第2章 多臂老虎机问题(MAB问题)2.1 问题描述2.1.1 问题定义2.1.2 形式化描述2.1.3 累积懊悔2.1.4 估计期望奖励 2.2 解决方法…

CSS 【详解】CSS 函数(含 calc,min,max,clamp,cubic-bezier,env,steps 等)

函数描述CSS 版本attr()返回选择元素的属性值。2calc()允许计算 CSS 的属性值,比如动态计算长度值。3cubic-bezier()定义了一个贝塞尔曲线(Cubic Bezier)。3hsl()使用色相、饱和度、亮度来定义颜色。3hsla()使用色相、饱和度、亮度、透明度来定义颜色。3linear-grad…

Bert 变种, T5模型

NLP-预训练模型-2019-NLU:DistilBERT【 BERT模型压缩】【模型大小减小了40%(66M),推断速度提升了60%,但性能只降低了约3%】_distillbert-CSDN博客 https://zhuanlan.zhihu.com/p/673535548 大语言模型系列-T5_t5模型…

【机器学习】必会数学知识:一文掌握数据科学核心数学知识点(上),值得收藏~

核心数学知识点 1、引言2、数据科学必会数学知识2.1 线性代数2.2 微积分2.3 概率论2.4 数理统计2.5 随机过程2.6 数据分布2.7 贝叶斯统计2.8 线性回归2.9 逻辑回归2.10 矩阵分解2.11 主成分分析(PCA)2.12 奇异值分解(SVD) 3、总结…

【Git 入门】初始化配置与新建仓库

文章目录 前言配置git新建仓库仓库的概念创建仓库命令总结前言 在现代软件开发中,版本控制系统已经成为了不可或缺的工具。其中,Git 是最为广泛使用的版本控制系统之一。Git 不仅可以帮助我们管理和跟踪代码的变化,还可以方便地与他人协作。本文将介绍 Git 的基础知识,包括…

【人工智能大语言模型技术发展研究报告 2024】

文末‍有福利! 人工智能作为引领新一轮科技产业革命的战略性技术和新质生产力重要驱动力,正在引发经济、社会、文化等领域的变革和重塑,2023 年以来,以 ChatGPT、GPT-4 为代表的大模型技术的出台,因其强大的内容生成及…

提升教师健康,聚焦智慧校园人事系统的职工体检功能

智慧校园人事管理系统内置的职工体检管理,是专为教职员工设计的一项健康管理创新实践,巧妙融合先进信息技术,致力于为教职工提供更加便捷、易懂且持续性的健康检查与管理支持。该服务从多个维度出发,全面呵护教职工的身心健康。 该…