【java设计模式之工厂模式实践】手把手

工厂方法模式(Factory Method)

简单工厂模式不是23种设计模式之一,他可以理解为工厂模式的一种简单的特殊实现。

基础版

// 工厂类
public class CoffeeFactory {public Coffee create(String type) {if ("americano".equals(type)) {return new Americano();}if ("mocha".equals(type)) {return new Mocha();}if ("cappuccino".equals(type)) {return new Cappuccino();}return null;}
}
// 产品基类
public interface Coffee {
}// 产品具体类,实现产品基类接口
public class Cappuccino implements Coffee {
}

基础版是最基本的简单工厂的写法,传一个参数过来,判断是什么类型的产品,就返回对应的产品类型。但是这里有一个问题,就是参数是字符串的形式,这就很容易会写错,比如少写一个字母,或者小写写成了大写,就会无法得到自己想要的产品类了,同时如果新加了产品,还得在工厂类的创建方法中继续加if,于是就有了升级版的写法。

升级版

 // 使用反射创建对象// 加一个static变为静态工厂public static Coffee create(Class<? extends Coffee> clazz) throws Exception {if (clazz != null) {return clazz.newInstance();}return null;}

升级版就很好的解决基础版的问题,在创建的时候在传参的时候不仅会有代码提示,保证不会写错,同时在新增产品的时候只需要新增产品类即可,也不需要再在工厂类的方法里面新增代码了。

实践

背景

在做大数据etl项目时,使用Seatunnel对不同数据源(mysql、sqlsever、Oracle等)进行采集或加工到任意数仓(hive、mysql、doris等),对于Seatunnel script的生成,mysql到各种数仓,sqlsever到各种数仓等,用传统if else实现创建各个Source或sink端的实例时,显得和low,直接暴露代码水平。
原始代码如下:

// 获取Seatunnel Source
private JdbcSource getSource(DataSourceDto syncDataSource, StringBuffer querySql, String result_table_name) {StringBuffer url = new StringBuffer();String driver = "";switch (syncDataSource.getType()) {// mysqlcase 0:url.append(syncDataSource.getLinkAddress() + "?serverTimezone=GMT%2b8");driver = DBTypeEnum.MYSQL.getDriver();break;// sql servercase 2:url.append(syncDataSource.getLinkAddress() + ";encrypt=true;trustServerCertificate=true");driver = DBTypeEnum.SQLSERVER.getDriver();break;// hanacase 4:url.append(syncDataSource.getLinkAddress());driver = DBTypeEnum.HANA.getDriver();break;}// sourceJdbcSource source = new JdbcSource(result_table_name);source.setUrl(url.toString()).setUser(syncDataSource.getUserName()).setPassword(syncDataSource.getPassword()).setQuery(querySql.toString()).setDriver(driver).setConnection_check_timeout_sec(100);return source;}
// 获取Seatunnel sink/*** 获取hive sink** @param result_table_name* @param modeTblName* @return*/private HiveSink getHiveSink(String result_table_name, String modeTblName) {// sinkHiveSink hiveSink = new HiveSink(result_table_name);hiveSink.setTableName(modeTblName).setDbName(hive_db_name).setMetastoreUri(super.getMetastoreUri());return hiveSink;}/*** doris sink** @param resultTableName* @param modeTblName* @return*/private Sink getDorisSink(String resultTableName, String modeTblName) {DorisSink dorisSink = new DorisSink(resultTableName);dorisSink.setFenodes(dorisEndpoint).setQueryPort(Integer.valueOf(dorisQueryPort)).setUsername(dorisDbUserName).setPassword(dorisDbPassword).setDatabase(dorisDB).setTable(modeTblName).setSinkEnable2pc(true).setSinkEnableDelete(true);return dorisSink;}private JdbcSink getJdbcSink(String result_table_name, String modeTblName, DataSourceDto dataSource) {// sinkLinkedList<String> pKeys = new LinkedList<>();
//        pKeys.add("M_SYS_ROW_PRIMARY_KEY");JdbcSink jdbcSink = new JdbcSink(result_table_name);jdbcSink.getPrimaryKeys().addAll(pKeys);jdbcSink.setDatabase(dataSource.getInstanceName()).setTable(modeTblName).setUrl(dataSource.getLinkAddress() + "?serverTimezone=GMT%2b8&rewriteBatchedStatements=true").setUser(dataSource.getUserName()).setPassword(dataSource.getPassword()).setDriver(DBTypeEnum.MYSQL.getDesc());return jdbcSink;}

从上面代码很直观看出,此人水平就在一个初级状态,那么,该怎么提升代码B格呢?通过分析发现,这种使用工厂模式比较适合(还有什么模式,大牛们可以给一些更好的建议,一起up)
使用设计模式实现,代码如下:

private JdbcSource getSource(DataSourceDto syncDataSource, StringBuffer querySql, String result_table_name) {
// 使用静态工厂模式获取不同实例AbstractSource source = SourceFactory.create(syncDataSource.getType(), result_table_name);String driver = DBTypeEnum.getEnumByCode(source.getSourceType()).getDriver();source.setUrl(syncDataSource.getLinkAddress()).setUser(syncDataSource.getUserName()).setPassword(syncDataSource.getPassword()).setQuery(querySql.toString()).setDriver(driver).setConnection_check_timeout_sec(100);return source;}
// 静态工场创建实例
public class SourceFactory {public static AbstractSource create(int type, String result_table_name) {if (DBTypeEnum.getEnumByCode(type) == null) {return null;} else if (DBTypeEnum.getEnumByCode(type).equals(DBTypeEnum.MYSQL)) {return new MysqlSource(result_table_name);} else if (DBTypeEnum.getEnumByCode(type).equals(DBTypeEnum.SQLSERVER)) {return new SqlSeverSource(result_table_name);} else if (DBTypeEnum.getEnumByCode(type).equals(DBTypeEnum.HANA)) {return new HanaSource(result_table_name);}return null;}
}
// 抽象共通属性
public abstract class AbstractSource extends JdbcSource {public AbstractSource(String result_table_name) {super(result_table_name);}public abstract int getSourceType();}
// mysql数据源Source适配
public class MysqlSource extends AbstractSource {public MysqlSource(String result_table_name) {super(result_table_name);}@Overridepublic int getSourceType() {return DBTypeEnum.MYSQL.getCode();}@Overridepublic JdbcSource setUrl(String url) {return super.setUrl(url + "?serverTimezone=GMT%2b8");}}
// hana
public class HanaSource extends AbstractSource {public HanaSource(String result_table_name) {super(result_table_name);}@Overridepublic int getSourceType() {return DBTypeEnum.HANA.getCode();}@Overridepublic JdbcSource setUrl(String url) {return super.setUrl(url);}
}
// sqlsever
public class SqlSeverSource extends AbstractSource {public SqlSeverSource(String result_table_name) {super(result_table_name);}@Overridepublic int getSourceType() {return DBTypeEnum.SQLSERVER.getCode();}@Overridepublic JdbcSource setUrl(String url) {return super.setUrl(url +";encrypt=true;trustServerCertificate=true");}}

已上代码是针对Seatunnel Source的一些优化和封装,还有querySql、sink等都可以类似的实现,感谢各位看官能看到这里!

写到最后

最近公司效益很差,没有奖金,更提出了降薪等政策。程序员这几年不如搬砖工,被定义为新型“农民工”的 那一刻,已经注定我们要像 农民工那样活着,不管在任何环境,努力提升自己,日拱一卒,功不唐捐。如果你现在还处于温水中的青蛙,那等待你的将是摆上餐桌。共同加油吧,come on man!!!

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

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

相关文章

渲染农场怎么渲染照片级效果图?

当讨论3D渲染的真实性时&#xff0c;不可避免地会将目光投向渲染农场。这些基于云的计算大军&#xff0c;专门负责逐帧打造接近现实的画面效果&#xff0c;无论是在电影动画还是在效果图制作等行业&#xff0c;都扮演着重要的支撑角色。对观众来说&#xff0c;画面的真实性几乎…

探索LLM在广告领域的应用——大语言模型的新商业模式和新个性化广告的潜力

概述 在网络搜索引擎的领域中&#xff0c;广告不仅仅是一个补充元素&#xff0c;而是构成了数字体验的核心部分。随着互联网经济的蓬勃发展&#xff0c;广告市场的规模已经达到了数万亿美元&#xff0c;并且还在持续扩张。广告的经济价值不断上升&#xff0c;它已经成为支撑大…

单调栈|84.柱状图中最大的矩形

力扣题目链接 // 版本一 class Solution { public:int largestRectangleArea(vector<int>& heights) {int result 0;stack<int> st;heights.insert(heights.begin(), 0); // 数组头部加入元素0heights.push_back(0); // 数组尾部加入元素0st.push(0);// 第一…

C++入门基础(四)

目录 auto关键字(C11)类型别名思考auto的使用细则auto与指针和引用结合起来使用在同一行定义多个变量 auto不能推导的场景auto不能作为函数的参数auto不能直接用来声明数组 复杂场景下的auto 基于范围的for循环(C11)范围for的语法范围for的使用条件 指针空值---nullptr(C11)C98…

go动态创建/增加channel并处理数据

背景描述 有一个需求&#xff0c;大概可以描述为&#xff1a;有多个websocket连接&#xff0c;因此消息会并发地发送过来&#xff0c;这些消息中有一个标志可以表明是哪个连接发来的消息&#xff0c;但只有收到消息后才能建立channel或写入已有channel&#xff0c;在收消息前无…

【vue-echarts】 报错问题解决 “Error: Component series.pie not exists. Load it first.“

目录 问题描述解决【解决1】【解决2】 问题描述 使用 vue-echarts 时导入的文件 import VChart from vue-echarts/components/ECharts import echarts/lib/chart/line import echarts/lib/chart/bar import echarts/lib/chart/pie import echarts/lib/component/legend impor…

SourceTree打开就闪退

问题背景&#xff1a;Windows 10 系统提示更新&#xff0c;然后SourceTree没有正常关闭&#xff0c;导致系统升级后打开该软件闪退&#xff0c;系统重启也无法解决。 1、打开文件位置 右键“Sourcetree”桌面快捷图标&#xff0c;点击“打开文件所在位置” 2、找到Local目录…

虚拟机装CentOS镜像

起先&#xff0c;是先安装一个VM虚拟机&#xff0c;再去官方网站之类的下载一些镜像&#xff0c;常见镜像有CentOS镜像&#xff0c;ubantu镜像&#xff0c;好像还有一个树莓还是什么的&#xff0c;软件这块&#xff0c;日新月异&#xff0c;更新太快&#xff0c;好久没碰&#…

【大模型】1. 深度学习框架和推理框架概念

深度学习框架&#xff1a;用于构建、训练和部署神经网络模型&#xff0c;包含&#xff1a;TensorFlow、PyTorch、OneFlow等 深度学习模型交换格式ONNX&#xff1a;实现不同深度学习框架之间的模型转换和互操作性 推理框架&#xff1a; NCNN&#xff1a;一个为手机端极致优化…

在Excel中使用正则提取单元格内容

在办公自动化的浪潮中&#xff0c;Excel 作为数据处理的利器&#xff0c;一直在不断进化。最近&#xff0c;我注意到了不坑盒子Office插件一个非常实用的功能更新——bk_regex_string 公式。这个功能对于我们这些日常需要处理大量文本和数据的办公人员来说&#xff0c;无疑是一…

HNU-人工智能-实验4-基于Resnet的分类器

前言 本实验是自选实验&#xff0c;可以在给定范围内选择。 我刚刚提交了实验报告&#xff0c;暂时不准备放出我自己的实验报告&#xff0c;大概在截止提交之后我再放。 之所以这么着急写blog&#xff0c;是想便利还没做实验的同学。 如果选择的也是这个“毒蘑菇识别”的分类器…

c++ 线程交叉场景试验

1.需求 1.处理一个列表的数据&#xff0c;要求按照列表的数据处理10个数据 2.可以使用多线程处理&#xff0c;但是针对每个线程&#xff0c;1~10的处理顺序不能变。 3.每个数据的处理必须原子&#xff0c;即只有一个线程可以针对某个数据进行处理&#xff0c;但是10个数据是可…

资源池管理

资源池相关概念 1、什么是资源池 资源池是灵活管理资源的逻辑抽象。资源池可以分组为层次结构&#xff0c;用于对可用的CPU和内存资源按层次结构进行分区。 2、为什么使用资源池 使用资源池可以委派对主机(或集群)资源的控制权&#xff0c;在使用资源池划分群集内的所有资 源时…

jdk环境安装

jdk安装 创建软件安装的目录 mkdir -p /bigdata/{soft,server} /bigdata/soft 安装文件的存放目录 /bigdata/server 软件安装的目录 把安装的软件上传到/bigdata/soft 目录 解压到指定目录 -C :指定解压到指定目录 tar -zxvf /bigdata/soft/jdk-8u241-linux-x64.tar.gz -C /b…

道可道,非常道,名可名,非常名;学习道德经新解读!打破思想钢印——早读(逆天打工人爬取热门微信文章解读)

你读过道德经吗? 引言Python 代码第一篇 洞见 原来这就是&#xff1a;穷人的思想钢印第二篇 人民日报 来了&#xff01;新闻早班车要闻社会政策 结尾 知识始于好奇 终于智慧 好奇心驱使我们探索 而智慧则是自由思想的结晶 引言 玄之又玄 众妙之门 今天真的是大开我的眼界 我之…

2024 cleanmymac有没有必要买呢,全反面分析

在使用mac时&#xff0c;小编遇到了运行内存不足、硬盘空间不足的情况。遇到这种情况&#xff0c;我们可以借助经典的电脑深度清理软件——CleanMyMac X&#xff0c;清理不常用的软件和系统垃圾&#xff0c;非常好用&#xff01;不过&#xff0c;有许多网友发现CleanMyMac X有免…

掌握 nmcli 命令,轻松管理网络连接

课程目标 本课程将指导你如何在 RHEL8 系统中使用 nmcli 命令配置和管理网络连接。通过本课程的学习&#xff0c;你将掌握以下技能&#xff1a; 查看现有网络连接和设备状态添加新的以太网和 Wi-Fi 连接为连接配置静态 IP 地址、子网掩码、默认网关和 DNS 服务器启用、禁用和…

mvc 异步请求、异步连接、异步表单

》》》 利用Jquery ajax 》》》 mvc 异步表单 c# MVC 添加异步 jquery.unobtrusive-ajax.min.js 方法 具–>Nuget程序包管理器–>程序包管理器控制台 在控制台输入&#xff1a;PM>Install-Package Microsoft.jQuery.Unobtrusive.Ajax –version 3.0.0 回车执行即可在…

PM说|还有不会DISC的项目经理?

DISC行为模型是一种常用于职场中的人际交往工具&#xff0c;它通过对个体的行为特点进行分类和分析&#xff0c;帮助人们更好地理解自己和他人的行为方式&#xff0c;从而更加高效地进行沟通和合作。在项目管理过程中&#xff0c;多方沟通是必备工作技能&#xff0c;如何利用DI…

四级英语翻译随堂笔记

降维表达&#xff1a;中译英&#xff0c;英译英 没有强调主语&#xff0c;没有说明主语&#xff1a;用被动 但如果实在不行&#xff0c;再增添主语 不会就不翻译&#xff0c;不要乱翻译 以xxx为背景&#xff1a;against the backdrop of the xxx eg:against the backdrop of…