uni-app 经验分享,从入门到离职(年度实战总结:经验篇)——上传图片以及小程序隐私保护指引设置

文章目录

  • 🔥年度征文
  • 📋前言
    • ⏬关于专栏
  • 🎯关于上传图片需求
  • 🎯前置知识点和示例代码
    • 🧩uni.chooseImage()
    • 🧩uni.chooseMedia()
      • 📌uni.chooseImage() 与 uni.chooseMedia()
    • 🧩uni.chooseFile()
  • 🎯关于小程序隐私保护指引设置
    • 🧩解决方法
  • 📝最后


在这里插入图片描述

🔥年度征文

在这里插入图片描述
活动地址:年度征文|回顾 2023,赢专属铭牌等定制大奖

白马过隙,转瞬之间 23 年的进度条已经快达到 100%,在迎接 24 年到来的同时,我们不妨来回顾一下这充满许多值得回忆时刻的 23年。过去的一年里,我们都经历了很多事情,或许经历了许多重要的时刻和学习机会;或许扩展了自己的知识领域;或许提升了自己的技术水平等等。接下来我来分享一下我在 23 年的一些代码笔记以及实战项目笔记。
在这里插入图片描述


📋前言

这篇文章是本专栏 uni-app 的项目经验篇,该文章将为大家分享在 uni-app 开发中的项目实战经验,本篇文章的主题是关于小程序上传图片官方 API 的使用,以及一些版本问题等等。除此之外,还有前段时间新发布的小程序隐私保护指引设置的新内容,包括如何解决类似隐私问题和如何设置隐私保护指引。

⏬关于专栏

本专栏主要是分享和介绍从零到一学习和使用的 uni-app 的笔记和个人经验。通过个人的学习经验和工作经验来给大家分享关于 uni-app 开发的技巧,以及快速入门的诀窍等等。

专栏主页:uni-app_黛琳ghz的博客-CSDN博客


🎯关于上传图片需求

在小程序中上传图片是很常见的交互功能,也是软件开发中不可缺少的功能,无论是在浏览器还是小程序中,都有很多需要用户上传图片的操作,接下来我们一起来看下有哪些应用场景,然后具体分析下需求。
在这里插入图片描述
应用场景:注册审核,在注册的流程中可能涉及到上传图片的需求,比如说身份证审核,个人信息等等审核,这个时候就需要用户上传图片到后台,进行审核;修改头像,这个功能是最常见的一个上传图片应用场景,用户从相册上传一张图片作为用户头像;表单提交,这个也是经常可以见到的应用场景,比如说问卷调查中需要上传图片的模块,或者任务提交的上传图片和上传任务描述这种应用场景。

需求分析:这里以注册审核的应用场景为例子,我们来分析一下这个需求,比如说该小程序注册要走审核流程,需要上传图片进行审核,首先授权完手机号码,然后填写用户的个人资料,如地址信息等等,接下来是上传图片的模块,比如说审核身份证、银行卡、健康证、认证资料等等,这些步骤都涉及到上传图片的功能。

分析完应用场景和需求之后,我们一起来看看在 uni-app 中可以用哪些 API 来实现上传图片的功能。


🎯前置知识点和示例代码

🧩uni.chooseImage()

uni.chooseImage() 是 uniapp 框架提供的一个 API,用于从本地相册或相机选择图片。 使用该方法可以打开系统的图片选择界面,让用户选择一张或多张图片。选择完成后,可以获取到选择的图片的临时文件路径。

❗PS:App端如需要更丰富的相机拍照API(如直接调用前置摄像头),参考plus.camera。

关于该方法的参数说明:

参数名类型必填说明平台差异说明
countNumber最多可以选择的图片张数,默认9见下方说明
sizeTypeArray<String>original 原图,compressed 压缩图,默认二者都有App、微信小程序、支付宝小程序、百度小程序
extensionArray<String>根据文件拓展名过滤,每一项都不能是空字符串。默认不过滤。H5(HBuilder X2.9.9+)
sourceTypeArray<String>album 从相册选图,camera 使用相机,默认二者都有。如需直接开相机或直接选相册,请只使用一个选项
cropObject图像裁剪参数,设置后 sizeType 失效App 3.1.19+
successFunction成功则返回图片的本地文件路径列表 tempFilePaths
failFunction接口调用失败的回调函数小程序、App
completeFunction接口调用结束的回调函数(调用成功、失败都会执行)

下面是 uni.chooseImage() 方法的使用示例:

uni.chooseImage({count: 1, // 最多可以选择的图片张数,默认为9sizeType: ['original', 'compressed'], // 可以指定原图或压缩图,默认为['original', 'compressed']sourceType: ['album', 'camera'], // 可以指定图片来源是相册还是相机,默认为['album', 'camera']// 选择图片成功success: function (res) {// 关于 tempFilePaths 在下文会介绍其注意事项var tempFilePaths = res.tempFilePaths;// 在这里可以对选择的图片进行处理,比如显示、上传等操作console.log('选择的图片路径:', tempFilePaths);},// 选择图片失败fail: function (err) {console.log('选择图片失败:', err.errMsg);}
});

在上述代码中,通过调用 uni.chooseImage() 方法,可以打开图片选择界面。可以通过设置 count 来指定最多选择的图片张数,sizeType 来指定选择的图片类型(原图或压缩图),sourceType 来指定图片来源(相册或相机)。

选择成功后,success 回调函数会被调用,可以在回调函数中获取选择的图片的临时文件路径(tempFilePaths)。在回调函数中,可以对选择的图片进行进一步处理,比如显示到页面上、上传到服务器等操作。如果选择图片失败,fail 回调函数会被调用,可以在回调函数中处理错误信息。

❗注意:文件的临时路径,在应用本次启动期间可以正常使用,如需持久保存,需在主动调用 uni.saveFile,在应用下次启动时才能访问得到。success 返回参数说明:

参数名类型说明
tempFilePathsArray<String>图片的本地文件路径列表
tempFilesArray<Object>、Array<File>图片的本地文件列表,每一项是一个 File 对象

关于其他详细的知识点和使用方法可以到 uni-app 官网查看,比如说这个 Tips 还是非常有用,需要的读者到官网(https://uniapp.dcloud.net.cn/api/media/image.html#chooseimage)查阅。
在这里插入图片描述


🧩uni.chooseMedia()

uni.chooseMedia() 是 uniapp 框架提供的一个 API,用于从本地相册或相机选择图片或视频。 使用该方法可以打开系统的图片/视频选择界面,让用户选择一张或多张图片或一个视频。选择完成后,可以获取到选择的图片/视频的临时文件路径。(兼容性如下图)在这里插入图片描述
关于该方法的参数说明:

参数名类型默认值必填说明
countNumber9(注意:ios不可大于9)最多可以选择的文件个数
mediaTypeArray<string>[‘image’, ‘video’]文件类型
sourceTypeArray<string>[‘album’, ‘camera’]图片和视频选择的来源
maxDurationNumber10拍摄视频最长拍摄时间,单位秒。时间范围为 3s 至 30s 之间
sizeTypeArray<string>[‘original’, ‘compressed’]仅对 mediaType 为 image 时有效,是否压缩所选文件
cameraString‘back’仅在 sourceType 为 camera 时生效,使用前置或后置摄像头
successfunction接口调用成功的回调函数
failfunction接口调用失败的回调函数
completefunction接口调用结束的回调函数(调用成功、失败都会执行)

下面是 uni.chooseMedia() 方法的使用示例:

uni.chooseMedia({count: 1, // 最多可以选择的图片或视频数量,默认为9mediaType: ['image', 'video'], // 可以指定选择的媒体类型为图片或视频,默认为['image', 'video']sourceType: ['album', 'camera'], // 可以指定图片/视频来源是相册还是相机,默认为['album', 'camera']maxDuration: 10, // 指定选择的视频的最大时长,单位秒,默认为60秒success: function (res) {// 关于 tempFilePaths 跟上文的注意事项类似var tempFiles = res.tempFiles;// 在这里可以对选择的图片或视频进行处理,比如显示、上传等操作console.log('选择的图片/视频路径:', tempFiles);},fail: function (err) {console.log('选择图片/视频失败:', err.errMsg);}
});

在上述代码中,通过调用 uni.chooseMedia() 方法,可以打开图片/视频选择界面。可以通过设置 count 来指定最多选择的图片或视频数量,mediaType 来指定选择的媒体类型(图片或视频),sourceType 来指定图片/视频来源(相册或相机),maxDuration 来指定选择的视频的最大时长。(具体使用方法和参数可以移步到官网查询和学习使用)

选择成功后,success 回调函数会被调用,可以在回调函数中获取选择的图片/视频的临时文件路径(tempFiles)。在回调函数中,可以对选择的图片/视频进行进一步处理,比如显示到页面上、上传到服务器等操作。如果选择图片或视频失败,fail 回调函数会被调用,可以在回调函数中处理错误信息。

📌uni.chooseImage() 与 uni.chooseMedia()

注意看下面这个图的红框部分,在微信小程序基础库 2.21.0 版本开始, wx.chooseImage 停止维护了,因此在开发过程中,我们在选择上传图片的方法时,需要留意下停止维护是否会影响到项目的后期迭代更新。因此可以使用 uni.chooseMedia 代替,以获得更好的兼容性和功能支持。
在这里插入图片描述
二者区别:

  • 功能:uni.chooseImage() 只能选择图片文件,而 uni.chooseMedia() 可以选择图片和视频文件。
  • 参数:在使用 uni.chooseImage() 时,可以通过设置 count 来指定最多选择的图片数量,而在使用 uni.chooseMedia() 时,可以通过设置 count 来指定最多选择的图片或视频数量。(等等)
  • 此外,uni.chooseMedia() 还可以通过设置 mediaType 来指定选择的媒体类型(图片或视频),以及通过设置 maxDuration 来指定选择的视频的最大时长。

🧩uni.chooseFile()

除了上面两个方法,这里还有一个方法也可以做到上传图片,但是不建议优先考虑使用 uni.chooseFile() 这个方法来进行上传图片的操作。因为 uni.chooseFile() 是 uniapp 框架提供的一个 API(仅兼容 H5),用于从本地选择文件。 该 API 主要用于选择非媒体文件,如果选择的文件是媒体文件,则可以用另外的专用API(如图片选择、视频选择、多媒体文件选择,含图片视频)。(兼容性如下图)
在这里插入图片描述
关于该方法的参数说明:

参数名类型默认值必填说明平台差异说明
countNumber100最多可以选择的文件数量不同平台的最大值可能会有差异
typeString‘all’所选的文件的类型不同平台支持的文件类型可能会有差异
extensionArray<String>根据文件拓展名过滤,每一项都不能是空字符串。默认不过滤。不同平台可能对拓展名的支持有差异
sourceTypeArray<String>[‘album’,‘camera’](仅在type为image或video时可用)album 从相册选图,camera 使用相机,默认二者都有。如需直接开相机或直接选相册,请只使用一个选项不同平台可能对相册和相机的支持有差异
successFunction成功则返回图片的本地文件路径列表 tempFilePaths
failFunction接口调用失败的回调函数
completeFunction接口调用结束的回调函数(调用成功、失败都会执行)

下面是 uni.chooseFile() 方法的使用示例:

uni.chooseFile({count: 1, // 最多可以选择的文件数量,默认为1type: 'all', // 可以指定选择的文件类型,如:image/video/audio/file,也可以使用 all,表示所有文件类型都可以选择,默认为 allsuccess: function (res) {var tempFilePaths = res.tempFilePaths;// 在这里可以对选择的文件进行处理,比如上传等操作console.log('选择的文件路径:', tempFilePaths);},fail: function (err) {console.log('选择文件失败:', err.errMsg);}
});

在上述代码中,通过调用 uni.chooseFile() 方法,可以打开文件选择界面。可以通过设置 count 来指定最多选择的文件数量,type 来指定选择的文件类型。

选择成功后,success 回调函数会被调用,可以在回调函数中获取选择的文件的临时文件路径(tempFilePaths)。在回调函数中,可以对选择的文件进行进一步处理,比如上传到服务器等操作。如果选择文件失败,fail 回调函数会被调用,可以在回调函数中处理错误信息。


🎯关于小程序隐私保护指引设置

上面介绍完上传图片的功能和使用案例,我们可以接着思考,既然我们要上传图片到程序或后台,那么上传图片就要读取到用户的手机相册或电脑的文件夹(编译器调试情况下或 PC 端打开小程序),这里就涉及到了一个隐私的问题,因此接下来我们一起来看一下关于小程序隐私保护指引设置,首先通过我的实际例子来给大家分享一下我从出现问题到解决问题的过程。

说到这点,其实也算是对个人 23 年接手的这一个项目做一个技术总结和经验分享吧,在微信官方更新小程序隐私保护指引设置的这个公告之前,小程序中的上传图片功能是正常的,但是在某一天,客户反馈说在注册过程中无法上传图片,因此针对这个问题,提出了三个排查方向,第一是前端上传图片类型错误了,导致前端判断逻辑有误、第二是后端接口的问题,第三是 API 的问题。逐一排查后,发现都不是这个问题,于是重点排查了 API 的问题,我通过输出 API 上传失败的原因和 fail 函数的输出来看,发现无论是在真机调试还是编译器上传都会出现这个报错。报错为:chooseImage:fail api scope is not declared in the privacy agreement,意思就是隐私协议中未声明 fail-api 作用域。
在这里插入图片描述
在这里插入图片描述
接下来对症下药,针对这个报错找解决方案即可,通过资料搜索和官网查询,发现也有不少开发者也同时遇到了这个问题,说明不是无缘无故冒出来的 bug,因此断定为官网修改 API 或发布新规则所导致。到该小程序的后台消息一看,发现新发布了一条关于小程序隐私保护指引设置的公告,公告这样说到:“为规范开发者的用户个人信息处理行为,保障用户的合法权益,自2023年9月15日起,对于涉及处理用户个人信息的小程序开发者,微信要求,仅当开发者主动向平台同步用户已阅读并同意了小程序的隐私保护指引等信息处理规则后,方可调用微信提供的隐私接口。”
在这里插入图片描述

🧩解决方法

知道了问题所在和微信官方给出的公告说明之后,我们可以很快的针对性的去解决这个问题,接下来分享一下解决方法。

首先我要到该小程序的后台提交协议信息,步骤为:进入首页,点击左侧导航栏的设置 => 功能设置 => 用户隐私保护指引设置 => 去填写信息提交审核。具体如下图。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这里我们可以勾选“选中的照片或视频”这个选项(上传图片所需),其他则根据实际项目需要勾选即可。只有在指引中声明所处理的用户个人信息,才可以调用平台提供的对应接口或组件。若未声明,对应接口或组件将无法调用成功。

除此之外还可以配置用户隐私授权弹窗,微信提供了 wx.onNeedPrivacyAuthorization(function callback) 接口,意为用户触发了一个微信侧未记录过同意的隐私接口调用,开发者可通过响应该事件选择提示用户的时机。此外,微信还提供了 wx.requirePrivacyAuthorize(Object object) 接口,可用于模拟触发 onNeedPrivacyAuthorization 事件。仅有在指引中声明所处理的用户个人信息,才可以调用平台提供的对应接口或组件。若未声明,对应接口或组件将直接禁用。
在这里插入图片描述
如要进行代码提审,开发者需先自行声明是否有采集用户隐私,如有,则需在提审页面-「用户隐私保护设置」选择“采集用户隐私”。
在这里插入图片描述
通过上面一系列的方法,我也是解决这次项目出现的问题了,亲测有效,审核通过之后,稍等片刻,项目重新编译就好了。这次发现问题解决问题的经验是非常宝贵的,通过这次项目的事故也让我在开发的过程中更加仔细了,除此之外我也会时刻关注微信官方发布的最新规则和公告等等,避免出现影响项目正常运行的情况,如果是迫不得已也要预留好解决方案和备用方案。


📝最后

到此就是本篇文章的全部内容了,这篇文章记录的主要内容是微信小程序的上传图片功能选择和使用对比以及小程序隐私保护指引设置。回顾 2023年,我开始接触了 uni-app 和微信小程序的开发,在开发和学习的过程中,我遇到了很多问题和挑战,同时也积累了很多实战技巧和经验,这篇文章是博主 uni-app 专栏第一篇年度实战总结的文章,后续还会不断的更新更多关于 uni-app 的干货、实战经验、学习经验,期待你的关注和留言。
在这里插入图片描述

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

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

相关文章

【playwright】新一代自动化测试神器playwright+python系列课程14_playwright网页相关操作_获取网页标题和URL

Playwright 网页操作_获取网页标题和URL 在做web自动化测试时&#xff0c;脚本执行完成后需要进行断言&#xff0c;判断脚本执行是否存在问题。在断言时通常选择一些页面上的信息或者页面上元素的状态来断言&#xff0c;使用网页标题或url来断言就是常见的断言方式&#xff0c…

Java-NIO篇章(2)——Buffer缓冲区详解

Buffer类简介 Buffer类是一个抽象类&#xff0c;对应于Java的主要数据类型&#xff0c;在NIO中有8种缓冲区类&#xff0c;分别如下&#xff1a; ByteBuffer、 CharBuffer、 DoubleBuffer、 FloatBuffer、 IntBuffer、 LongBuffer、 ShortBuffer、MappedByteBuffer。 本文以它的…

Zabbix分布式监控系统概述、部署、自定义监控项、邮件告警

目录 前言 &#xff08;一&#xff09;业务架构 &#xff08;二&#xff09;运维架构 一、Zabbix分布式监控平台 &#xff08;一&#xff09;Zabbix概述 &#xff08;二&#xff09;Zabbix监控原理 &#xff08;三&#xff09;Zabbix 6.0 新特性 1. Zabbix server高可用…

10- OpenCV:基本阈值操作(Threshold)

目录 1、图像阈值 2、阈值类型 3、代码演示 1、图像阈值 &#xff08;1&#xff09;图像阈值&#xff08;threshold&#xff09;含义&#xff1a;是将图像中的像素值划分为不同类别的一种处理方法。通过设定一个特定的阈值&#xff0c;将像素值与阈值进行比较&#xff0c;根…

BEESCMS靶场小记

MIME类型的验证 image/GIF可通过 这个靶场有两个小坑&#xff1a; 1.缩略图勾选则php文件不执行或执行出错 2.要从上传文件管理位置获取图片链接&#xff08;这是原图上传位置&#xff09;&#xff1b;文件上传点中显示图片应该是通过二次复制过去的&#xff1b;被强行改成了…

路由器的妙用:使用无线路由器无线桥接模式充当电脑的无线网卡

文章目录 需求说明第一步&#xff1a;重置、连接路由器第二步&#xff1a;设置无线桥接模式第三步&#xff1a;电脑连接路由器上网 需求说明 在原路由无线覆盖的范围内&#xff0c;使用无网卡台式和其他主机&#xff0c;并且有闲置的无线路由器或者网线太短&#xff0c;可以使…

添加边界值分析测试用例

1.1创建项目成功后会自动生成封装好的函数&#xff0c;在这些封装好的函数上点击右键&#xff0c;添加边界值分析测试用例&#xff0c;如下图所示。 1.2生成的用例模版是不可以直接运行的&#xff0c;需要我们分别点击它们&#xff0c;让它们自动生成相应测试用例。如下图所示&…

nas-群晖docker查询注册表失败解决办法(平替:使用SSH命令拉取ddns-go)

一、遇到问题 群晖里面的docker图形化界面现在不能直接查询需要下载的东西&#xff0c;原因可能就是被墙了&#xff0c;那么换一种方式使用SSH命令下载也是可以的&#xff0c;文章这里以在docker里面下载ddns-go为例子。 二、操作步骤 &#xff08;一&#xff09;打开群晖系统…

《Redis:NoSQL演进之路与Redis深度实践解析》

文章目录 关于NoSQL为什么引入NoSQL1、单机MySQL单机年代的数据库瓶颈 2、Memcached&#xff08;缓存&#xff09; MySQL 垂直拆分 &#xff08;读写分离&#xff09;3、分库分表水平拆分MySQL集群4、如今的网络架构5、总结 NoSQL的定义NoSQL的分类 Redis入门Redis能干嘛&…

原生SSM整合(Spring+SpringMVC+MyBatis)案例

SSM框架是Spring、Spring MVC和MyBatis三个开源框架的整合&#xff0c;常用于构建数据源较简单的web项目。该框架是Java EE企业级开发的主流技术&#xff0c;也是每一个java开发者必备的技能。下面通过查询书籍列表的案例演示SSM整合的过程. 新建项目 创建文件目录 完整文件结…

google网站流量怎么获取?

流量是一个综合性的指标&#xff0c;可以说做网站就是为了相关流量&#xff0c;一个网站流量都没有&#xff0c;那其实就跟摆饰品没什么区别 而想从谷歌这个搜索引擎里获取流量&#xff0c;一般都分为两种方式&#xff0c;一种是网站seo&#xff0c;另一种自然就是投广告&#…

线程的使用

线程的创建方式 1、实现Runnable Runnable规定的方法是run()&#xff0c;无返回值&#xff0c;无法抛出异常 实现Callable 2、Callable规定的方法是call()&#xff0c;任务执行后有返回值&#xff0c;可以抛出异常 3、继承Thread类创建多线程 继承java.lang.Thread类&#xff0…

C++ //练习 1.15 编写程序,包含第14页”再探编译“中讨论的常见错误。熟悉编译器生成的错误信息。

C Primer&#xff08;第5版&#xff09; 练习 1.15 练习 1.15 编写程序&#xff0c;包含第14页”再探编译“中讨论的常见错误。熟悉编译器生成的错误信息。 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09; 工具&#xff1a;vim 代码块 /******************…

[足式机器人]Part2 Dr. CAN学习笔记-Ch04 Advanced控制理论

本文仅供学习使用 本文参考&#xff1a; B站&#xff1a;DR_CAN Dr. CAN学习笔记 - Ch04 Advanced控制理论 1. 绪论2. 状态空间表达State-Space Representation3. Phase Portrait相图&#xff0c;相轨迹3 1. 1-D3 2. 2-D3 3. General Form3 4. Summary3.5. 爱情中的数学-Phase …

.NetCore Flurl.Http 升级到4.0后 https 无法建立SSL连接

Flurl.Http-3.2.4 升级到 4.0.0 版本后&#xff0c;https请求异常&#xff1a;Call failed. The SSL connection could not be established. 如下图&#xff1a; Flurl.Http-3.2.4版本绕过https的代码&#xff0c;对于 Flurl.Http-4.0.0 版本来说方法不再适用&#xff0c;3.2.…

【萤火虫系列教程】3/5-Adobe Firefly 创意填充

003-Adobe Firefly 创意填充 创意填充 登录账号后&#xff0c;在主页点击创意填充的【生成】按钮&#xff0c;进入到创意填充页面 我们可以上传自己的图像 一键抠图 点击【背景】就可以把主图抠出来 点击【反转】就可以把背景抠出来 点击【清除】就可以恢复到图片原来…

表的增删改查 进阶(一)

&#x1f3a5; 个人主页&#xff1a;Dikz12&#x1f525;个人专栏&#xff1a;MySql&#x1f4d5;格言&#xff1a;那些在暗处执拗生长的花&#xff0c;终有一日会馥郁传香欢迎大家&#x1f44d;点赞✍评论⭐收藏 目录 数据库约束 约束类型 NOT NUll 约束 UNIQUE 约束 D…

K8S对外服务ingress

Sevice作用体现在两个方面 集群内部 不断跟踪pod的变化&#xff0c;更新endpoint中的pod对象&#xff0c;基于pod的ip地址不断发现的一种服务发现机制 集群外部 类似负载均衡器&#xff0c;把流量&#xff08;ip端口&#xff09;&#xff0c;不涉及转发url&#xff08;http ht…

STM32WLE5JC介绍

32位 ARM Cotrex-M4 CPU 32MHz晶体振荡器 32 kHz RTC振荡器与校准 20x32位备份寄存器 引导程序支持USART和SPI接口 介绍 STM32WLE5/E4xx远程无线和超低功耗器件嵌入了强大的超低功耗LPWAN兼容无线电解决方案&#xff0c;支持以下调制&#xff1a;LoRa&#xff0c;&#xff08…

设计模式-简单工厂

设计模式-简单工厂 简单工厂模式是一个集中管理对象创建&#xff0c;并根据条件生成所需类型对象的设计模式&#xff0c;有助于提高代码的复用性和维护性&#xff0c;但可能会导致工厂类过于复杂且违反开闭原则。 抽象提取理论&#xff1a; 封装对象创建过程解耦客户端与产品…