01 设计模式-创造型模式-工厂模式

  • 工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一,它提供了一种创建对象的方式,使得创建对象的过程与使用对象的过程分离。

  • 工厂模式提供了一种创建对象的方式,而无需指定要创建的具体类。

  • 通过使用工厂模式,可以将对象的创建逻辑封装在一个工厂类中,而不是在客户端代码中直接实例化对象,这样可以提高代码的可维护性和可扩展性。

设计模式,最近持续更新中,如需要请关注

如果你觉得我分享的内容或者我的努力对你有帮助,或者你只是想表达对我的支持和鼓励,请考虑给我点赞、评论、收藏。您的鼓励是我前进的动力,让我感到非常感激。

文章目录

  • 1 概要
  • 2 实现
  • 3 Demo代码
  • 4 开发案例
    • 4.1 算法执行服务里,不同的任务数据来源不同,执行脚本类型不同,结果处理不同,使用工厂模式
    • 4.2 网络还原时,不同的采集数据,解析处理方式不同

1 概要

意图
定义一个创建对象的接口,让其子类决定实例化哪一个具体的类。工厂模式使对象的创建过程延迟到子类。

主要解决
接口选择的问题。

何时使用
当我们需要在不同条件下创建不同实例时。

如何解决
通过让子类实现工厂接口,返回一个抽象的产品。

关键代码
对象的创建过程在子类中实现。

应用实例

  1. 汽车制造:你需要一辆汽车,只需从工厂提货,而不需要关心汽车的制造过程及其内部实现。
  2. Hibernate:更换数据库时,只需更改方言(Dialect)和数据库驱动(Driver),即可实现对不同数据库的切换。

优点

  1. 调用者只需要知道对象的名称即可创建对象。
  2. 扩展性高,如果需要增加新产品,只需扩展一个工厂类即可。
  3. 屏蔽了产品的具体实现,调用者只关心产品的接口。

缺点
每次增加一个产品时,都需要增加一个具体类和对应的工厂,使系统中类的数量成倍增加,增加了系统的复杂度和具体类的依赖。

使用场景

  1. 日志记录:日志可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志的位置。
  2. 数据库访问:当用户不知道最终系统使用哪种数据库,或者数据库可能变化时。
  3. 连接服务器的框架设计:需要支持 “POP3”、“IMAP”、“HTTP” 三种协议,可以将这三种协议作为产品类,共同实现一个接口。
  4. 在算法执行服务中,每个任务需要处理的数据来源不同,根据数据类型创建对应的数据出来handle类,不用关心handle里的内部处理逻辑

注意事项
工厂模式适用于生成复杂对象的场景。如果对象较为简单,通过 new 即可完成创建,则不必使用工厂模式。使用工厂模式会引入一个工厂类,增加系统复杂度。

结构
工厂模式包含以下几个主要角色:

  • 抽象产品(Abstract Product):定义了产品的共同接口或抽象类。它可以是具体产品类的父类或接口,规定了产品对象的共同方法。
  • 具体产品(Concrete Product):实现了抽象产品接口,定义了具体产品的特定行为和属性。
  • 抽象工厂(Abstract Factory):声明了创建产品的抽象方法,可以是接口或抽象类。它可以有多个方法用于创建不同类型的产品。
  • 具体工厂(Concrete Factory):实现了抽象工厂接口,负责实际创建具体产品的对象。

2 实现

我们将创建一个 Shape 接口和实现 Shape 接口的实体类。下一步是定义工厂类 ShapeFactory。

FactoryPatternDemo 类使用 ShapeFactory 来获取 Shape 对象。它将向 ShapeFactory 传递信息(CIRCLE / RECTANGLE / SQUARE),以便获取它所需对象的类型。
请添加图片描述

3 Demo代码

在这里插入图片描述
Shape

/*** 公共接口*/
public interface Shape {void draw();
}

Circle

/*** 圆形,形状的实现类*/
public class Circle implements Shape {@Overridepublic void draw() {System.out.println("Inside Circle::draw() method.");}
}

Rectangle

/*** 矩形,形状的实现类*/
public class Rectangle implements Shape {@Overridepublic void draw() {System.out.println("Inside Rectangle::draw() method.");}
}

Square

/*** 方形,形状的实现类*/
public class Square implements Shape {@Overridepublic void draw() {System.out.println("Inside Square::draw() method.");}
}

ShapeFactory

/*** 形状工厂类【根据不同的参数创建对应的实例】*/
public class ShapeFactory {//使用 getShape 方法获取形状类型的对象public Shape getShape(String shapeType) {if (shapeType == null) {return null;}if (shapeType.equalsIgnoreCase("CIRCLE")) {return new Circle();} else if (shapeType.equalsIgnoreCase("RECTANGLE")) {return new Rectangle();} else if (shapeType.equalsIgnoreCase("SQUARE")) {return new Square();}return null;}
}

FactoryPatternDemo

/***    总结:用来根据不同的参数创建对象*/
public class FactoryPatternDemo {public static void main(String[] args) {ShapeFactory shapeFactory = new ShapeFactory();//获取 Circle 的对象,并调用它的 draw 方法Shape shape1 = shapeFactory.getShape("CIRCLE");//调用 Circle 的 draw 方法shape1.draw();//获取 Rectangle 的对象,并调用它的 draw 方法Shape shape2 = shapeFactory.getShape("RECTANGLE");//调用 Rectangle 的 draw 方法shape2.draw();//获取 Square 的对象,并调用它的 draw 方法Shape shape3 = shapeFactory.getShape("SQUARE");//调用 Square 的 draw 方法shape3.draw();}
}

效果
在这里插入图片描述

4 开发案例

4.1 算法执行服务里,不同的任务数据来源不同,执行脚本类型不同,结果处理不同,使用工厂模式

请添加图片描述
说明:

  • TaskAbstractFactory命名成抽象工厂,可以创建出来DataSetHandle工厂,ScriptExecuteHandle工厂,ResultHandle工厂,但是实现时,时间关系,简化成简单工厂模式。
  • 工厂返回的对象,每次都是新创建出来的,因为这些handle每次创建初始化的参数是不同的,和下面的第二个案例有所不同

在这里插入图片描述

工厂类

/*** 任务抽象工厂类,创建各种处理类* @since 2023 -10-08 16:13*/
public class TaskAbstractFactory {private static final Logger LOGGER = LoggerFactory.getLogger(TaskAbstractFactory.class);/*** Gets script execute handle.** @param scriptParam the script param* @param algoId the algo id* @return the script execute handle*/public static ScriptExecuteHandle getScriptExecuteHandle(ScriptParam scriptParam, String algoId) {if (Constants.ScriptType.PYTHON.equals(scriptParam.getScriptType()) || Constants.ScriptType.PYTHON3.equals(scriptParam.getScriptType())) {return new PythonScriptExecuteHandle(scriptParam);} else {LOGGER.error("The algorithm type is not supported. algoId: {} ,scriptType: {} ", algoId,scriptParam.getScriptType());throw new CommonServiceException(AIModelError.ALGO_TYPE_NOT_SUPPORTED);}}/*** Gets data set handle list.** @param dataSets the data sets* @return the data set handle list*/public static List<DataSetHandle> getDataSetHandleList(List<InputDataSource> dataSets) {ArrayList<DataSetHandle> dataSetHandleList = new ArrayList<>(10);for (InputDataSource inputDataSource : dataSets) {dataSetHandleList.add(getDataSetHandle(inputDataSource));}return dataSetHandleList;}/*** Gets data set handle.** @param inputDataSource the input data source* @return the data set handle*/public static DataSetHandle getDataSetHandle(InputDataSource inputDataSource) {if (Constants.DataSourceType.MINIO_FILE.equalsIgnoreCase(inputDataSource.getDatatype())) {DataSetHandle dataSetHandle = new S3DataSetHandle(inputDataSource.getDataSourceInfo(),inputDataSource.getDataSourceConfig());// 进行数据源校验dataSetHandle.checkDataSource();return dataSetHandle;} else if (Constants.DataSourceType.HDFS_FILE.equalsIgnoreCase(inputDataSource.getDatatype())) {DataSetHandle dataSetHandle = new HdfsDataSetHandle(inputDataSource.getDataSourceInfo(),inputDataSource.getDataSourceConfig());// 进行数据源校验dataSetHandle.checkDataSource();return dataSetHandle;} else {LOGGER.error("The data source type is not supported. datatype: {} ", inputDataSource.getDatatype());throw new CommonServiceException(AIModelError.DATA_TYPE_NOT_SUPPORTED);}}/*** Gets result handle.** @param calculateParam the calculate param* @param scriptParam the script param* @return the result handle*/public static ResultHandle getResultHandle(CalculateParam calculateParam, ScriptParam scriptParam) {// 【预留】 设置结果集存放的数据源。目前所有的算法都有数据集,取数据集的第一个数据源作为结果上传的数据源OutputDataSource outputDataSource = getOutDataSource(calculateParam.getDataSets().get(0));if (Constants.CustomizedAlgoId.POTENTIAL_GUEST_ALGO_ID.equals(calculateParam.getAlgoId())) {// 定制化的处理方式,需要走特有的处理方式。此类算法,只能提前预置后return new PotentialGuestResultHandle(scriptParam, outputDataSource);} else {// 任务结果走默认处理方式,此类算法可以通过算法管理界面可以添加return new ResultHandle(scriptParam, outputDataSource);}}private static OutputDataSource getOutDataSource(InputDataSource inputDataSource) {return new OutputDataSource(inputDataSource.getDatatype(), inputDataSource.getDataSourceConfig());}}

使用

    public TaskEntity(TaskInfo taskInfo, CalculateParam calculateParam, String algoPackDir, String localFileDir) {this.scriptParam = getScriptParam(calculateParam, algoPackDir, localFileDir);this.taskInfo = taskInfo;this.shellParamHandle = TaskAbstractFactory.getScriptExecuteHandle(scriptParam, calculateParam.getAlgoId());this.dataSetHandleList = TaskAbstractFactory.getDataSetHandleList(calculateParam.getDataSets());this.resultHandle = TaskAbstractFactory.getResultHandle(calculateParam, scriptParam);}

其他说明
设计是工厂创建实例的是子类,返回的是父类。多态的体现。同事父类有默认方法,子类是对父类的扩展, 或者重写。如下:
DataSetHandle

/*** 数据集处理父类* @since 2023 -09-15 15:35*/
public abstract class DataSetHandle {private static final Logger LOGGER = LoggerFactory.getLogger(DataSetHandle.class);/*** The Data source info.*/protected String dataSourceInfo;/*** The Data source config.*/protected String dataSourceConfig;/*** Instantiates a new Data set handle.** @param dataSourceInfo the data source info* @param dataSourceConfig the data source config*/public DataSetHandle(String dataSourceInfo, String dataSourceConfig) {this.dataSourceInfo = dataSourceInfo;this.dataSourceConfig = dataSourceConfig;}/*** Check data source.*/public void checkDataSource() {// 对参数的json格式进行校验if (!MyStringUtil.checkJson(dataSourceInfo)) {LOGGER.error("dataSourceInfo json format error.");throw new CommonServiceException(AIModelError.PARAM_ERROR, "dataSourceInfo json format error.");}if (StringUtils.isNotEmpty(dataSourceConfig) && !MyStringUtil.checkJson(dataSourceConfig)) {LOGGER.error("dataSourceConfig json format error.");throw new CommonServiceException(AIModelError.PARAM_ERROR, "dataSourceConfig json format error.");}}/*** Handle data.** @param taskId the task id* @param localFileDir the local file dir*/public abstract void handleData(String taskId, String localFileDir);}

S3DataSetHandle

/*** S3或者minio类型的数据集处理类* @since 2023 -09-15 15:35*/
public class S3DataSetHandle extends DataSetHandle {private static final Logger LOGGER = LoggerFactory.getLogger(S3DataSetHandle.class);/*** Instantiates a new S 3 data set handle.** @param dataSourceInfo the data source info* @param dataSourceConfig the data source config*/public S3DataSetHandle(String dataSourceInfo, String dataSourceConfig) {super(dataSourceInfo, dataSourceConfig);}/*** Check data source.*/@Overridepublic void checkDataSource() {// 1 父类进行参数json格式的校验super.checkDataSource();// 2 具体子类,进行特性校验List<S3DataSourceInfo> s3DataSourceList = JSON.parseArray(dataSourceInfo, S3DataSourceInfo.class);for (S3DataSourceInfo s3DataSource : s3DataSourceList) {// 目前S3,仅支持zip文件if (!Constants.FileType.ZIP.equalsIgnoreCase(s3DataSource.getFileType())) {LOGGER.error("The file type is not supported. fileType:{}", s3DataSource.getFileType());throw new CommonServiceException(AIModelError.PARAM_ERROR,"The file type is not supported. fileType: " + s3DataSource.getFileType());}if (StringUtils.isEmpty(s3DataSource.getFileId()) || StringUtils.isEmpty(s3DataSource.getStoreDirName())) {LOGGER.error("fileId and storeDirName cannot be empty.");throw new CommonServiceException(AIModelError.PARAM_ERROR, "fileId and storeDirName cannot be empty.");}}}/*** Handle data.** @param taskId the task id* @param localFileDir the local file dir*/@Overridepublic void handleData(String taskId, String localFileDir) {// 1 获取配置S3DataSourceConfig s3DataSourceConfig = JSON.parseObject(dataSourceConfig, S3DataSourceConfig.class);// 2 初始化S3客户端S3ClientUtils s3ClientUtils = S3ClientUtils.getInstance(s3DataSourceConfig);for (S3DataSourceInfo s3DataSourceInfo : JSON.parseArray(dataSourceInfo, S3DataSourceInfo.class)) {InputStream s3InputStream = null;try {// 3 获取数据流s3InputStream = s3ClientUtils.download(s3DataSourceConfig.getBucketName(),s3DataSourceInfo.getFileId());// 4 将文件保存在本地磁盘saveFileToLocal(s3InputStream, s3DataSourceInfo, taskId, localFileDir + taskId);} finally {MyIOUtils.closeInputStream(s3InputStream);}}}
}

4.2 网络还原时,不同的采集数据,解析处理方式不同

说明:

  • 创建对象由spring类管理,创建出来的对象是单例的,这个案例1有所不同,案例1,每个类初始化的参数不同。这个案例对象初始化方式一样,只是处理逻辑不同。
  • 在vimpim对象是,因为参数不同所有每次都需要new

工厂类:

/*** The type Ods process factory.** @since 2024 -06-11 10:54*/
@Slf4j
@Service
public class OdsProcessFactory {private static final List<VimPimModelDto> VIM_PIM_MODEL_V2_LIST = new ArrayList<>();private static final String VIM_PIM_MODEL_V2_FILE_PATH = "2.json";private static final List<String> VIM_PIM_MODEL_V2_WHITE_LIST = Arrays.asList();private static final List<VimPimModelDto> VIM_PIM_MODEL_V3_LIST = new ArrayList<>();private static final String VIM_PIM_MODEL_V3_FILE_PATH = "3.json";private static final List<String> VIM_PIM_MODEL_V3_WHITE_LIST = Arrays.asList();/*** The Data source.*/@Resource(name = "gauss")DataSource dataSource;@Autowiredprivate VimPimRepository vimPimRepository;@Autowiredprivate VnfMaeCnDataProcessDomainService vnfMaeCnDataProcessDomainService;@Autowiredprivate VnflocLcmDataProcessDomainService vnflocLcmDataProcessDomainService;static {// 初始化模型数据initModel(VIM_PIM_MODEL_V2_FILE_PATH, VIM_PIM_MODEL_V2_WHITE_LIST, VIM_PIM_MODEL_V2_LIST);initModel(VIM_PIM_MODEL_V3_FILE_PATH, VIM_PIM_MODEL_V3_WHITE_LIST, VIM_PIM_MODEL_V3_LIST);}private static void initModel(String vimPimModelFilePath, List<String> vimPimModelWhiteList,List<VimPimModelDto> vimPimModelList) {}/*** Gets ods process service.** @param taskDto the task dto* @param dataFormat the data format* @return the ods process service*/public DataProcessDomainService getOdsProcessService(CollectionTaskDto taskDto, int dataFormat) {if (OdsParseConstants.OdsDataFormat.VNF_MAECN == dataFormat|| OdsParseConstants.OdsDataFormat.NIC_DSP == dataFormat) {return vnfMaeCnDataProcessDomainService;} else if (OdsParseConstants.OdsDataFormat.VIM_OV2 == dataFormat|| OdsParseConstants.OdsDataFormat.PIM_OV2 == dataFormat) {return getVimPimDataProcessV2DomainService();} else if (OdsParseConstants.OdsDataFormat.VIM_OV3 == dataFormat|| OdsParseConstants.OdsDataFormat.PIM_OV3 == dataFormat) {return getVimPimDataProcessV3DomainService();} else if (OdsParseConstants.OdsDataFormat.VNFLOC_LCM == dataFormat) {return vnflocLcmDataProcessDomainService;} else {// 采集来的数据格式不支持log.warn("Incorrect data dataFormat. taskId:{}, tasksSn:{}, dataFormat:{} ", taskDto.getTaskId(),taskDto.getTaskSn(), dataFormat);}return null;}public VimPimDataProcessV2DomainService getVimPimDataProcessV2DomainService() {return new VimPimDataProcessV2DomainService(VIM_PIM_MODEL_V2_LIST, dataSource, vimPimRepository);}public VimPimDataProcessV3DomainService getVimPimDataProcessV3DomainService() {return new VimPimDataProcessV3DomainService(VIM_PIM_MODEL_V3_LIST, dataSource, vimPimRepository);}
}

在这里插入图片描述

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

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

相关文章

1.2.3 TCP IP模型

TCP/IP模型&#xff08;接网叔用&#xff09; 网络接口层 网络层 传输层 应用层 理念&#xff1a;如果某些应用需要“数据格式转换”“会话管理功能”&#xff0c;就交给应用层的特定协议去实现 tip&#xff1a;数据 局部正确不等于全局正确 但是&#xff0c;数据的 全局正…

数码准备记录

1.数据结构 常见的数据结构包括数组、链表、栈、队列、树&#xff08;如二叉树、B树、B树&#xff09;、图等 2.队列和栈的区别 队列是一种先入先出的数据结构&#xff0c;即最先加入的元素被最先移除&#xff1b; 栈是一种后进后出的数据结构&#xff0c;即最后加入的元素…

SQL Server的介绍以及存储过程和函数的使用

SQL Server 是由微软开发的一个关系型数据库管理系统(RDBMS)。以下是关于 SQL Server 的详细介绍: 一、主要特点 强大的数据处理能力: 支持大规模数据存储和处理,可以处理海量的结构化数据。无论是小型企业应用还是大型企业级系统,SQL Server 都能提供高效的数据存储和检…

数据分箱:如何确定分箱的最优数量?

选择最优分箱可以考虑以下几种方法&#xff1a; 一、基于业务理解 分析业务背景&#xff1a;从业务角度出发&#xff0c;某些特征可能有自然的分组或区间划分。例如&#xff0c;年龄可以根据不同的人生阶段进行分箱&#xff0c;收入可以根据常见的收入等级划分。 优点&#x…

RTMP协议分析

理论 总体介绍 RTMP协议是应⽤层协议&#xff0c;是要靠底层可靠的传输层协议&#xff08;通常是TCP&#xff09;来保证信息传输的可靠性的。在基于传输层协议的链接建⽴完成后&#xff0c;RTMP协议也要客户端和服务器通过“握⼿”来建⽴基于传输层链接之上的RTMP Connection链…

《测试能否转产品经理?——优势与难点并存的转型之路》

引言 在软件行业中&#xff0c;测试人员和产品经理这两个角色似乎有着不同的定位和职责。然而&#xff0c;随着行业的发展和个人职业发展的需求&#xff0c;越来越多的测试人员开始思考一个问题&#xff1a;我能不能转产品经理呢&#xff1f; 一、测试转产品经理的优势 对产…

Collection 单列集合 List Set

集合概念 集合是一种特殊类 ,这些类可以存储任意类对象,并且长度可变, 这些集合类都位于java.util中,使用的话必须导包 按照存储结构可以分为两大类 单列集合 Collection 双列集合 Map 两种 区别如下 Collection 单列集合类的根接口,用于存储一系列符合某种规则的元素,它有两…

plsql查询Oracle数据库发现有的数据是乱码

原因&#xff1a;Oracle数据库字符集和plsql客户端所使用的字符集不一致。 查询时&#xff0c;可能因为解码问题导致解出错误的字符。 也可能插入时就没有使用正确的字符集&#xff0c;解码时用utf-8自然也无法解出正确的字符。 环境变量 NLS_LANG 定义了客户端使用的语言、地…

MySQL多表操作--外键约束多表关系

外键约束介绍 Mysql外键约束&#xff08;foreign key&#xff09;是表的一个特殊字段&#xff0c;常与主键约束一起使用。外键约束是一种用于维护两个表之间数据一致性的方法。它确保引用表中的每个值都存在于主表中的某个列中。外键约束通常用于实现数据库的参照完整性。对于两…

LeetCode 1343.大小为K且平均值大于等于阈值的子数组数目

题目&#xff1a; 给你一个整数数组 arr 和两个整数 k 和 threshold 。 请你返回长度为 k 且平均值大于等于 threshold 的子数组数目。 思路&#xff1a;定长滑动窗口 入 更新 出 代码&#xff1a; class Solution {public int numOfSubarrays(int[] arr, int k, int t…

Electron-(二)桌面应用的启动动画创建

一、概述 在很多桌面应用中都会有启动画面的显示。启动画面可以解决在启动时耗时较长&#xff0c;将每一步反馈给用户。另外一方面解决启动过程中的环境检查及检查结果的反馈。 在当今的桌面应用领域&#xff0c;启动动画已成为提升用户体验的重要组成部分。它不仅仅是一个简单…

【Linux】main函数的参数列表从何而来?

Linux系统进程通过exec系列函数启动新程序时&#xff0c;argc整型 、 argv数组 和 环境变量表 environ 会作为 exec 系列函数的参数&#xff0c;显式传递给新程序的 main 函数。 main函数的参数列表 在C语言中&#xff0c;main函数的标准参数列表通常如下所示&#xff1a; in…

极客wordpress模板

这是一个展示WordPress主题的网页设计。页面顶部有一个导航栏&#xff0c;包含多个选项&#xff0c;如“关于我们”、“产品中心”、“案例展示”、“新闻动态”、“联系我们”和“技术支持”。页面中间部分展示了多个产品&#xff0c;每个产品都有一个图片和简短的描述。页面下…

MySQL【知识改变命运】06

前言&#xff1a;在05这节数据结构里面&#xff0c;我们知道select * from 这个操作很危险&#xff0c;如果数据库很大&#xff0c;会把服务器资源耗尽&#xff0c;接下来提到的查询可以有效的限制返回记录 1&#xff1a;分页查询 分页查询可以有效控制一次查询出来的结果集的…

AutoSar AP CM原始数据流传输接口总结

一、原始数据流传输接口概述 自适应 AUTOSAR 通信管理通常基于面向服务的通信&#xff0c;但对于高级驾驶辅助系统&#xff08;ADAS&#xff09;应用&#xff0c;高效传输原始二进制数据流很重要&#xff0c;原始数据二进制流 API 为此提供了解决方案。它能与车辆外部传感器高…

【CTF刷题9】2024.10.19

[MoeCTF 2021]babyRCE 考点&#xff1a;关键词过滤&#xff08;绕过方法参考往期博客&#xff09; 来源&#xff1a;nssctf <?php$rce $_GET[rce]; if (isset($rce)) {if (!preg_match("/cat|more|less|head|tac|tail|nl|od|vi|vim|sort|flag| |\;|[0-9]|\*|\|\%|\&g…

TiDB 关联子查询及半连接的优化实践

作者&#xff1a; 数据源的TiDB学习之路 原文来源&#xff1a; https://tidb.net/blog/e9563a23 导读 TiDB 针对子查询语句会执行多种 子查询相关的优化 &#xff0c;以提升子查询的执行性能。半连接语句和关联子查询语句是常用的两类子查询&#xff0c;TiDB 优化器默认包…

《浙江工业大学学报》

《浙江工业大学学报》 国际标准刊号&#xff1a;ISSN 1006-4303&#xff0c;国内统一刊号&#xff1a;CN 33-1193/T。 本刊主要报道本校各学科最新的研究成果&#xff0c;并择优刊登相关学科的外稿。覆盖的学科主要有化学工程、机械工程、信息工程、建筑工程以及生物与环境工…

图像中的数值计算

目录 图像读取与形状图像数据展示图像数据操作超出范围的像素值处理 图像读取与形状 使用cv2.imread函数读取图像文件。图像的形状通过shape属性获取&#xff0c;格式为(高度, 宽度, 颜色通道数)。 import cv2img1 cv2.imread(bg.jpg) img2 cv2.imread(fish.jpg)print(img1…

Linux服务器安装SRAToolkit教程

SRAToolkit是由NCBI&#xff08;美国国家生物技术信息中心&#xff09;提供的一个工具集&#xff0c;用于下载、读取和转换SRA&#xff08;Sequence Read Archive&#xff09;格式的数据文件。这些数据文件包含了大规模的核酸序列数据&#xff0c;对于基因组学研究至关重要。本…