设计模式Java实现-工厂模式

✨这里是第七人格的博客✨小七,欢迎您的到来~✨

🍅系列专栏:设计模式🍅

✈️本篇内容: 工厂模式✈️

🍱本篇收录完整代码地址:https://gitee.com/diqirenge/design-pattern 🍱

楔子

记得刚入行的时候,听过一个段子,同样开发一个功能初级程序员要1天,中级程序员要2天,高级程序员要1个星期。当时以为是老油条划水(虽然肯定还是会划一点水,哈哈),但是其实更重要的还是设计思想的不同,经验丰富的程序员往往考虑的更多,不光是业务拓展性,更有程序拓展性。

需求背景

实现一个图片上传功能,逻辑很简单,就是把图片上传到对象存储,但是现在有两个服务商可以选择,他们分别是阿里云和腾讯云,并且现在没有敲定用哪一个,需要你先对接。他们提供的API各不相同,我们假设他们提供的API如下

渠道接口
阿里云void aliUpload(String fileName, String ossId, String token);
腾讯云String tencentUpload(String fileName, String base64, String appID, String appSecret);

分析设计

因为这2个接口的实现的定义不一样,所以我们最好能抽象出一个统一的接口,让子类去实现自己的业务逻辑,这样的好处是以后腾讯云有变更,就改腾讯云,阿里云有变更就改阿里云,两个子类互不影响(满足单一职责原则)。

又为了不让上层直接使用我们这个统一的方法,所以我们可以再抽象一个类,让他来决定用哪一个上传方式,相当于加了一层防腐,这里我们把他叫做工厂类(创建者与具体的业务解耦)。

再想一下拓展情况,如果以后又加一种上传方式,比如华为云,那我们修改起来也非常方便,只要再加一个子类就可以了,调用方可以不用变(满⾜开闭原则)。

UML图

根据分析设计,我们可以先画一个简单的UML图,后面通过UML图编码

工厂模式UML.png

模块名称

factory

模块地址

https://gitee.com/diqirenge/design-pattern/tree/master/src/main/java/com/run2code/design/creational/factory

模块描述

工厂模式代码示例

代码实现

1、首先我们模拟出两个外部接口

上传至oss

/*** 上传至oss* 关注公众号【奔跑的码畜】,一起进步不迷路** @author 第七人格* @date 2023/11/17*/
public class AliOss {public void aliUpload(String fileName, String ossId, String token) {System.out.println("ali upload 入参: " + fileName + " " + ossId + " " + token);System.out.println("ali 上传成功!");}
}

上传至cos

/*** 上传至cos* 关注公众号【奔跑的码畜】,一起进步不迷路** @author 第七人格* @date 2023/11/17*/
public class TencentCos {public String tencentUpload(String fileName, String base64, String appID, String appSecret) {System.out.println("tencent upload 入参: " + fileName + " " + base64 + " " + appID + " " + appSecret);return "成功上传到腾讯云";}
}

2、然后定义一个用于创建对象的接口或抽象类,让子类决定实例化哪一个类

抽象类

/*** 抽象的上传操作类,当然他也可以是一个接口* 关注公众号【奔跑的码畜】,一起进步不迷路** @author 第七人格* @date 2023/11/15*/
public abstract class BaseUpDownloader {/*** 执行文件上传操作(延迟到子类实现)** @param filePath 文件路径* @param fileName 文件名称* @param param    第三方参数* @return {@link String}*/public abstract String doUpload(String filePath, String fileName, Map<String, String> param);
}

上传子类 oss,继承了抽象类,并且调用了上传至oss的方法

/*** 上传子类 oss* 关注公众号【奔跑的码畜】,一起进步不迷路** @author 第七人格* @date 2023/11/15*/
public class AliOssUpDownloader extends BaseUpDownloader {private AliOss aliOss;public AliOssUpDownloader() {this.aliOss = new AliOss();}@Overridepublic String doUpload(String filePath, String fileName, Map<String, String> param) {aliOss.aliUpload(fileName, param.get("ossId"), param.get("token"));return "AliOssUpDownloader upload success";}
}

上传子类 cos,继承了抽象类,并且调用了上传至oss的方法

/*** 上传子类 cos,继承了抽象类,并且调用了上传至oss的方法* 关注公众号【奔跑的码畜】,一起进步不迷路** @author 第七人格* @date 2023/11/15*/
public class TencentUpDownloader extends BaseUpDownloader {private TencentCos tencentCos;public TencentUpDownloader() {this.tencentCos = new TencentCos();}@Overridepublic String doUpload(String filePath, String fileName, Map<String, String> param) {String result = tencentCos.tencentUpload(fileName, param.get("base64"), param.get("appID"), param.get("appSecret"));System.out.println(result);return "TencentUpDownloader upload success";}
}

3、创建一个工厂类,其中包含一个用于创建产品对象的方法。

/*** 上传的工厂类* 关注公众号【奔跑的码畜】,一起进步不迷路** @author 第七人格* @date 2023/11/17*/
public class UpDownloaderFactory {/*** 注册上传下载对象到工厂。** @param upDownloaderName 下载器名称* @return {@link BaseUpDownloader}*/public BaseUpDownloader registerUpDownloader(String upDownloaderName) {if ("tencent".equalsIgnoreCase(upDownloaderName)) {return new TencentUpDownloader();} else if ("ali".equalsIgnoreCase(upDownloaderName)) {return new AliOssUpDownloader();}return null;}
}

4、编写测试方法

/*** 测试工厂模式* 关注公众号【奔跑的码畜】,一起进步不迷路** @author 第七人格* @date 2023/11/17*/
public class UpDownloaderFactoryTest {/*** 测试调用阿里上传*/@Testpublic void testAli() {UpDownloaderFactory factory = new UpDownloaderFactory();BaseUpDownloader upDownloader = factory.registerUpDownloader("ali");Map<String, String> param = new HashMap<>();param.put("ossId", "ossId");param.put("token", "token");if (upDownloader == null) {return;}System.out.println("==========上传开始==========");String result = upDownloader.doUpload("/temp/file", "阿里文件.pdf", param);System.out.println("结果:" + result);System.out.println("==========上传结束==========");}/*** 测试调用腾讯上传*/@Testpublic void testTencent() {UpDownloaderFactory factory = new UpDownloaderFactory();BaseUpDownloader upDownloader = factory.registerUpDownloader("tencent");Map<String, String> param = new HashMap<>();param.put("base64", "base64");param.put("appID", "appID");param.put("appSecret", "appSecret");if (upDownloader == null) {return;}System.out.println("==========上传开始==========");String result = upDownloader.doUpload("/temp/file", "腾讯文件.pdf", param);System.out.println("结果:" + result);System.out.println("==========上传结束==========");}}

5、测试结果

①执行testAli方法

==========上传开始==========

ali upload 入参: 阿里文件.pdf ossId token

ali 上传成功!

结果:AliOssUpDownloader upload success

==========上传结束==========

②执行testTencent方法

==========上传开始==========

tencent upload 入参: 腾讯文件.pdf base64 appID appSecret

成功上传到腾讯云

结果:TencentUpDownloader upload success

==========上传结束==========

实现要点

  1. 定义一个用于创建对象的接口或抽象类,让子类决定实例化哪一个类。

    示例中为:BaseUpDownloader

  2. 创建一个工厂类,其中包含一个用于创建产品对象的方法。

    示例中,工厂类为:UpDownloaderFactory;创建产品对象的方法为:registerUpDownloader

  3. 在客户端代码中,通过调用工厂类的方法来创建所需的产品对象,而无需直接调用具体的产品类的构造函数。

    示例中为:

    UpDownloaderFactory factory = new UpDownloaderFactory();

    BaseUpDownloader upDownloader = factory.registerUpDownloader("ali");

总结

本文从模拟需求开始,带着读者一起学习了工厂模式,从上文可知工厂模式其实非常简单,掌握三大实现要点就可以了。所以小七在工作中使用工厂模式的频率也非常的高,但是工厂模式一般是不会单独使用的,他的好伙伴有策略模式、单例模式、模版模式等等,后面小七都会讲到。

本文由博客一文多发平台 OpenWrite 发布!

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

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

相关文章

Junit 测试中如何对异常进行断言

本文对在 Junit 测试中如何对异常进行断言的几种方法进行说明。 使用 Junit 5 如果你使用 Junit 5 的话,你可以直接使用 assertThrows 方法来对异常进行断言。 代码如下: Exception exception = assertThrows(NumberFormatException.class, () -> {new Integer("on…

Java的java.util.concurrent.ExecutorService简介

在Java并发编程的璀璨星空中&#xff0c;ExecutorService无疑是那颗最耀眼的明星。它不仅是Java并发编程的核心组件之一&#xff0c;更是构建高并发、高性能应用的秘密武器。今天&#xff0c;我们就来一场说走就走的探索之旅&#xff0c;揭开它的神秘面纱&#xff01; &#x1…

wordpress外贸建站公司歪建站新版网站上线

wordpress外贸建站公司 歪猫建站 歪猫WordPress外贸建站&#xff0c;专业从事WordPress多语言外贸小语种网站建设与外贸网站海个推广、Google SEO搜索引擎优化等服务。 https://www.waimaoyes.com/dongguan

【1小时掌握速通深度学习面试6】图神经网络-下

目录 23. GraphSage 24.简述图神经网络的推理机制在其他领域中的应用 与传统NN的区别&#xff08;GNN优点&#xff09; 23. GraphSage GraphSage出现之前的图网络方法需要图中所有的顶点在训练embedding的时候都出现&#xff0c;这些的方法本质上是transductive&#xff0c…

计算机是如何执行指令的

你好&#xff0c;我是 shengjk1&#xff0c;多年大厂经验&#xff0c;努力构建 通俗易懂的、好玩的编程语言教程。 欢迎关注&#xff01;你会有如下收益&#xff1a; 了解大厂经验拥有和大厂相匹配的技术等 希望看什么&#xff0c;评论或者私信告诉我&#xff01; 文章目录 一…

【数据结构】有关环形链表题目的总结

文章目录 引入 - 快慢指针思考 - 快慢指针行走步数进阶 - 寻找环形链表的头 引入 - 快慢指针 141-环形链表 - Leetcode 关于这道题&#xff0c;大家可以利用快慢指针&#xff0c;一个每次走两步&#xff0c;一个每次走一步&#xff0c;只要他们有一次相撞了就代表说这是一个链…

Django实验(远程访问+图片显示)

众所周知&#xff0c;Python除了不能生孩子什么都会。Python也是可以做web服务的。 Python做web有一个重点优势是&#xff1a;做一个快速的AI Demo。 第一步&#xff1a;安装一个版本5.0以上django 第二步&#xff1a;构建咱们的Django工程&#xff0c;我取名为BBQ django-adm…

仅为娱乐,Python中如何重定义True为False?

在Python中&#xff0c;True 和 False 是内建的布尔常量&#xff0c;分别代表逻辑上的真和假。它们是不可变的&#xff0c;且在Python语言规范中具有特殊地位&#xff0c;不能被用户直接重定义。尝试给 True 或 False 赋予新的值是违反Python语言规则的&#xff0c;这样的操作会…

(论文阅读-优化器)Orca: A Modular Query Optimizer Architecture for Big Data

目录 摘要 一、简介 二、背景知识 2.1 大规模并行处理 2.2 SQL on Hadoop 三、Orca架构 四、查询优化 4.1 优化工作流 4.2 并行查询优化 五、Metadata Exchange 六、可行性 6.1 Minimal Repros 6.2 优化器准确性测试 七、实验 八、相关工作 8.1 查询优化基础 8…

基于51单片机NEC协议红外遥控发送接收proteus仿真设计

1.主要功能&#xff1a; 设计一个51单片机红外遥控发射接收proteus仿真设计 功能要求&#xff1a; 1、使用单片机模拟红外遥控器发射红外编码&#xff1b; 2、利用从机接收红外编码&#xff0c;并将编码以16进制显示到数码管上。 需注意仿真中51单片机芯片是兼容的&#x…

最近惊爆谷歌裁员

Python团队还没解散完&#xff0c;谷歌又对Flutter、Dart动手了。 什么原因呢&#xff0c;猜测啊。 谷歌裁员Python的具体原因可能是因为公司在进行技术栈的调整和优化。Python作为一种脚本语言&#xff0c;在某些情况下可能无法提供足够的性能或者扩展性&#xff0c;尤其是在…

X 推出 Stories 功能,由 Grok AI 生成新闻摘要

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…