用户名
Email
论坛
潜水/灌水快乐,沉淀知识,认识更多同行。
ToB圈子
加入IT圈,遇到更多同好之人。
朋友圈
看朋友圈动态,了解ToB世界。
ToB门户
了解全球最新的ToB事件
博客
Blog
排行榜
Ranklist
文库
业界最专业的IT文库,上传资料也可以赚钱
下载
分享
Share
导读
Guide
相册
Album
记录
Doing
帖子
本版
文章
帖子
ToB圈子
用户
免费入驻
产品入驻
解决方案入驻
公司入驻
案例入驻
登录
·
注册
只需一步,快速开始
账号登录
立即注册
找回密码
用户名
自动登录
找回密码
密码
登录
立即注册
首页
找靠谱产品
找解决方案
找靠谱公司
找案例
找对的人
专家智库
悬赏任务
圈子
SAAS
IT评测·应用市场-qidao123.com
»
论坛
›
软件与程序人生
›
云原生
›
鸿蒙5.0开辟【模块化设计】架构
鸿蒙5.0开辟【模块化设计】架构
北冰洋以北
论坛元老
|
2025-3-12 16:13:42
|
显示全部楼层
|
阅读模式
楼主
主题
1009
|
帖子
1009
|
积分
3027
模块化设计理念
在大型软件工程中,一般会陪伴着多团队开辟,而各个团队之间,都是弱耦合交互,团队交付的业务之间以一种左券化形式的接口,定义了业务之间的接口,以此来满意各个团队的业务独立发展,互不影响,实现快速迭代演进,这就需要业务模块化。模块化是当代软件工程的核心原则之一,它通过将大型的复杂体系拆解为更小、更轻易管理和明确的部分——功能模块,来进步体系的可维护性和可拓展性。每个功能模块都是一个独立的单位,具有清晰定义的接口和职责,可以或许与其他模块交互以完成复杂的使命。
在HarmonyOS应用开辟中,模块化不但是一个设计原则,更是一种开辟实践。它旨在将应用步调拆分为多个功能模块,每个功能模块负责特定的功能或特性。功能模块可以独立开辟、编译和部署,也可以在不同的设备上灵活组合和调用。
应用步调包结构概念
在进行模块化设计时,需要考虑HarmonyOS的应用包结构选型,HarmonyOS的应用包结构是为了定义应用的组织方式,通过开辟态、编译态、发布态阶段应用步调包的形态,了解到不同包范例对应的使用场景以及使用规则。
Ability应用组件设计
HarmonyOS应用的业务逻辑需要通过[Ability组件]承载,根据业务设备以及业务诉求不同,需要考虑Ability组件的选择以及设计。在多设备的背景下,应用的形态不一定是传统移动设备上的单使命单窗口形式,在一些场景下,多使命多窗口的形态可以让用户获得更好的用户体验,提升使用效率。
例如在手机设备上:
条记应用,可让用户将信息从条记的一页复制到另一页。
文档编辑应用,可让用户同时打开编辑多个文档,可让用户将内容从一个文档复制或移动到另一个文档。
导航/打车应用,可以让导航后台运行,回到主页查找新的位置信息或其它信息。
购物类临时客服界面,可让用户通过使命管理快速从商品欣赏页切换回到客服会话界面,克制用户一层层打开查找。
应用付出/登录页面,可以切换至应用内其它页面查找并复制相关信息。
在大屏设备上,应用内的多个使命可以以多窗口的形式存在,用户可以并行利用应用的不同功能。
视频播放器应用,可让用户在观看播放内容的同时欣赏其他大概感兴趣的视频列表。
电子邮件应用,可让用户在撰写电子邮件的同时检察收到的邮件列表。
地点簿应用,可让用户并排比较多个职员的接洽信息。
阅读应用,可让用户在查阅所有标题概要后,打开多篇文章供稍后阅读。
对于这种类似独立应用一样的使命,每个使命对应一个UIAbility组件实例,并且每个使命可以单独显示一个窗口,对用户而言,可以在同个应用不同使命间切换,就像是单独的应用一样,并且在大屏设备上可以独立地移动、调整大小、显示和隐藏应用窗口。所以在进行功能设计时,需要对应用本身是否支持多使命多窗口,结合起来考虑Ability组件的设计,这影响整体工程模块化的结构。
对于单Ability的情况下,可以对应单窗口范例应用,或者通过多实例/指定实例实现的多使命类应用,例如普通的游戏应用这类情况下,发起采用单HAP来承载UIAbility。
对于多Ability有两种情况:
对于多窗口范例的应用,这类应用每个窗口对应不同的功能,通过不同的UIAbility承载,如上述例子中导航/打车应用,导航功能界面和主页属于不同的功能,并且要可以或许作为两个使命呈现给用户,可以将该模块作为Feature范例的HAP承载相应的UIAbility组件。
对于应用的一些拓展功能如卡片、分享业务,其不会作为单独的使命和窗口形态运行,但是由于其功能相对来说独立,并且是由体系提供的独立[ExtensionAbility]来承载,从更好拆分业务来考虑,也发起通过Feature范例的HAP承载单独的ExtensionAbility组件。
应用模块化选型
应用架构是给应用业务服务的,是从技能的角度思考业务怎样实现的;而工程模块化模型,是基于技能架构对代码工程所做的模块化技能选型,需要考虑技能到代码工程上怎样落地,只有代码工程模型的技能选型公道了,才气在包体积、性能、产物部署等取得一个最优的综合表现。
一般业务是分模块的,比如某购物软件,上面的业务就有主页导航、商品详情、购物车、付出、订单、个人信息等相关的模块;所以技能架构上,就会出现很多业务模块,模块之间是高内聚低耦合的,在代码工程上也就表现为模块(Module)。而在做代码工程模块化的技能选型上,因为Entry范例的HAP是工程默认存在的,且不能存在多个,所以主要考虑的就是几种模块范例:Feature范例的HAP模块,HAR模块和HSP模块。
在技能架构上的某个模块,做代码工程的选择时,是选择哪种模块范例,需要结合业务本身性子/模块的功能等因素综合考虑的。以基于应用常见的模块化模型,在实际的业务考虑中以下几种情况:
[共享模块]:某个功能模块(业务模块或者能力模块)需要在多个应用之间共享其代码逻辑和资源。
[按需加载模块]:某个功能模块,使用时由用户决定安装时机,动态从应用市场下载安装使用。
[多HAP/HSP引用雷同HAR包的影响]:从性能角度出发,需要淘汰多HAP/HSP对雷同HAR包的引用。
共享模块
对于大型软件,不同的业务以及基础能力会分为多个团队开辟,多团队之间需要代码仓隔离;如果某个或者多少个HAR工程模块是由某个团队负责开辟的,又想代码仓隔离,可以将这些HAR单独在独立的工程内开辟,将工程编译产物通过公司私有的OHPM仓进行发布和集成,如下图所示。
图1
多工程互助模式
这部分可以发布到OHPM仓的模块,叫做共享模块,可以将公共能力共享给多个应用使用,如公司内部多个应用使用某个公共能力网络库;或者也可以将该公共能力封装成库贡献给社区,给其他应用集成使用,这样的话这个模块也只能是HAR模块。
按需加载模块
随着应用业务扩大,应用给用户提供的功能越来越多,但是并非所有的功能都是用户常用的,根据用户运营陈诉分析,对于某些用户月活比较低的特性,可以将该特性做成按需加载模块。用户首次从应用市场安装时,仅会下载不包罗按需加载模块的内容,需要使用到对应功能时,由用户选择使用时下载安装对应的功能模块。
设计为按需加载模块有以下长处:
淘汰包体积:用户从应用市场首次下载的应用不包罗按需加载模块,用户看到的包体积淘汰,从而淘汰了用户下载和安装时间,淘汰了用户等待时间。
淘汰体系资源:应用安装之后所占用的空间也变少(节省ROM空间),应用启动时加载的特性少了(节省了RAM空间)。
架构演进:将特性定义为按需加载之后,对特性的定义和模块间的耦合关系进一步明确,有利于应用架构进一步演进。
如果某个特性做成了按需加载模块,该模块可以设计为Feature范例的HAP或者HSP,HAP和HSP都可以实现按需加载,区别在于Feature范例的HAP可以包罗Ability组件,结合前面的[Ability应用组件设计]以及业务是否需要按需加载,从整体上可以划分两个大的场景如下:
单HAP场景:如果只包罗一个UIAbility组件(包罗UIAbility多实例/指定实例),无需使用ExtensionAbility组件,优先采用单HAP(Entry范例的HAP)来实现应用开辟,其中根据是否需要实现按需加载的来决定选择HSP或者HAR作为模块。
多HAP场景:要实现多使命承载多个UIAbility组件,以及需要使用ExtensionAbility组件实现拓展功能,可以采用多HAP(即一个Entry范例的HAP+多个Feature范例的HAP)来实现应用开辟,每个HAP中包罗一个UIAbility组件或者一个ExtensionAbility组件,多个HAP情况下,根据是否具有公共能力决定模块的选型。
应用组件的设计,决定了模块化设计中是单HAP工程还是多HAP工程,在设计初期需要考虑应用的使命形态,来决定采用何种模块化结构。
多HAP/HSP引用雷同HAR包的影响
在应用开辟的过程中,可以使用[HSP]或[HAR]的共享包方式将同类的模块进行整合,用于实现多个模块或多个工程间共享ArkUI组件、资源等相关代码。
由于共享包的动态和静态差异,在多HAP/HSP引用雷同HAR包的情况下,会存在HAR包中的单例失效,从而影响到应用冷启动的性能。
图2
HAP包和HSP包分别引用雷同HAR包
如上图所示,工程内存在三个模块,HAP包为应用主入口模块,HSP为应用主界面显示模块,HAR_COMMON集成了所有通用工具类,其中funcResult为func方法的执行结果。
由于HAP和HSP模块同时引用HAR_COMMON模块时会破坏HAR的单例模式,所以HAP和HSP模块使用HAR_COMMON中的funcResult时,会导致func方法在两个模块加载时各执行一次,使得文件执行时间耗时增长。
如果仅从性能的角度考虑,可以使用以下方式进行修改,从而达到紧缩冷启动阶段耗时的目标。
图3
切换为HAP包和HAR包分别引用雷同HAR包
说明
在多HAP/HSP引用雷同HAR包的情况下,若HSP包和HAR包均能满意业务需求,发起将HSP包改成HAR包。
若使用的HSP为[集成态HSP],可跳过该优化方案。
在被引用HAR_COMMON包中写入功能示例。
// har_common/src/main/ets/utils/Utils.ets
const LARGE_NUMBER = 100000000;
function func(): number {
let count = 0;
while (count < LARGE_NUMBER) {
count++;
}
return count;
}
export let funcResult = func();
复制代码
分别通过使用HSP包和HAR包来引用该HAR_COMMON包中的功能进行性能对比实行。
使用HAP包和HSP包引用该HAR_COMMON包中的功能。
HAP包引用HAR_COMMON包中的功能。
// entry/src/main/ets/pages/Index.ets
import { MainPage } from 'hsp_library';
import { funcResult } from 'har_common';
复制代码
HSP包引用HAR_COMMON包中的功能。
// hsp_library/src/main/ets/pages/MainPage.ets
import { funcResult } from 'har_common';
复制代码
使用HAP包和HAR包引用该HAR_COMMON包中的功能。
HAP包引用HAR_COMMON包中的功能。
// entry/src/main/ets/pages/Index.ets
import { MainPage } from 'har_library';
import { funcResult } from 'har_common';
复制代码
HAR包引用HAR_COMMON包中的功能。
// har_library/src/main/ets/pages/MainPage.ets
import { funcResult } from 'har_common';
复制代码
使用[Launch模板],对优化前后启动性能进行对比分析。
分析阶段的起点为启动Ability(即H:void OHOS::AppExecFwk::MainThread::HandleLaunchAbility的开始点),阶段终点为应用第一次接到vsync(即H:ReceiveVsync dataCount:24Bytes now:timestamp expectedEnd:timestamp vsyncId:int的开始点)。
图4
优化前,使用HSP包
图5
优化后,使用HAR代替HSP
优化前后的对比数据如下:
方案阶段时长(毫秒)(优化前)使用HSP包3125(优化后)使用HAR代替HSP853.9 说明
上述示例为凸显出差异,func执行函数循环次数为100000000,开辟者实际修改后收益需根据实际情况测试。
从测试数据可以看出,将HSP更换为HAR包后,应用启动的阶段耗时明显紧缩。
单HAP工程
对于单窗口应用的APP工程而言,其仅包罗一个Entry范例的HAP,那么划分的模块则是根据是否有按需加载的需求,来考虑采用HAR模块和HSP模块。
不包罗按需加载模块
对于不需要按需加载且仅有一个Entry范例的HAP的App来讲,可以直接全部采用HAR进行开辟设计。如下图所示:
说明
这里说的仅有一个HAP指的是一种设备范例仅有一个HAP,而不是.app文件包里面仅有一个HAP。因为.app里面可以包罗其他设备的HAP包,如手表、大屏,进行多设备分发。
图6
非按需加载工程模型
上图工程架构中,除了产物模块层中与设备相关的HAP外,其他的均为HAR,这些被依赖的HAR,终极都会被编译进HAP中。
设计成HAR包有如下长处:
全部编译进HAP,无额外的HSP,节省HSP的安装和加载成本。
HAR在编译进HAP时,可以使用ArkTS的语言特性和编译器功能,做范例推断和编译优化。
代码工程架构简单,后续演进较为灵活。
包罗按需加载模块
在单HAP工程内,如果要实现按需加载功能,那么对应的组件需要采用HSP作为按需加载组件模块。在这种情况下,由于HAR是静态共享库,多个HAP/HSP如果依赖于同一份HAR,则该HAR在应用内会被存在多份。而HSP是动态共享库,其安装和加载均会有一些性能损失(相比于HAR),所以过多的HSP大概会影响安装效率和App启动性能,需要考虑现在App占用空间(App Size)是否瓶颈以及对启动性能的敏感水平,根据业务实际情况,在App Size与特性启动性能之间做好平衡。
说明
这里所提到的App Size指的是用户已经把按需加载模块安装之后,应用整体的大小。
App Size优先
对于App Size比较看重的,可以考虑将公共依赖的模块封装在一个HSP模块壳中,如下图所示:
图7
公共依赖模块通过HSP模块壳承载
hap_A依赖于独有的共享库har_A,同时需要依赖于har_C和har_D;而按需加载模块hsp_B依赖于独有的共享库har_B,同时需要依赖于har_C和har_D。
说明
这里的共享库har_A、har_B、har_C、har_D不一定本地工程,有大概是从ohpm仓上依赖下载的。
因为har_C和har_D同时被hap_A和hsp_B工程所依赖,所以为了节省App Size,可以将其封装到名为“common_hsp”的Module中,对外袒露har_C和har_D的接口,将har_C和har_D打包到common_hsp中,最后让hap_A和hsp_B依赖于common_hsp工程。common_hsp工程是无实际意义的,它仅是一个“模块壳”,是为了最小化App Size而存在的。
性能优先
对于性能比较敏感的,则不需要再封装一个公共的HSP模块,直接依赖公共HAR包:
图8
公共依赖模块使用HAR模块承载
因为公共HSP包需要安装和加载,所以会有一些性能损耗。对于启动性能敏感型的应用,则将hap_A和hsp_B直接依赖于har_C和har_D。终极编译产物里面有2个,hap_A.hap和hsp_B.hsp,但是这两个编译产物里面均会包罗har_C和har_D,App Size会比采用公共HSP模型大。
多HAP工程
对于同一个设备范例,如果要实现不同的独立功能模块,并且相对独立,以及具有单独的入口的功能特性,发起做成一个独立特性的HAP,按需下载安装。此时一个App包中,就会有多个HAP包,其中有且仅有一个Entry范例的HAP,其他的均是Feature范例的HAP。多HAP之间业务独立,但是大概会有业务能力共享,所以在进行模块化设计时,需要根据是否具有公共能力来进行选择。
包罗公共能力模块
对于具备公共能力模块的工程,和上述HAP+HSP组合是类似的,需要考虑在App Size与启动性能之间做平衡。
性能优先
一般多HAP应用架构普适性采用以下模型,除了产物组件中存在HAP包之外,其余的均是HAR包,如下图所示:
图9
多HAP工程模块表现图
从编译产物上看,多HAP之间是存在雷同的HAR包的(如har_2、har_3、har_C、har_D、harE),这样App Size大概会比较大,对于App Size不是瓶颈点的应用,或者HAR包的大小比较小,对App Size的影响可控,可以采用这种模型,淘汰了动态加载的性能损耗。
App Size 优先
上述的重复HAR包,其本质的题目就是HAR包怎样在HAP、HSP之间分布可以最小化App Size,淘汰HAR的重复编译打包,大的思路就是公共能力模块可以封装为公共HSP,最小化App Size,如下图所示:
图10
多HAP工程模块表现图
说明
需要注意,在应用间共享的HAR包,原则上是不允许依赖HSP包,因为HSP包是专属于应用,和bundleName进行了绑定,一旦HAR包依赖于应用内HSP,该HAR包就丢失了共享性,无法再给其他应用共享。
如上图所示,有3个HAP包(一个entry和两个feature),将公共的HAR包封装到HSP工程中,如common_wrap_hsp和feature_wrap_hsp,这两个HSP从严格意义上讲,不能称之为模块,它们仅能称之为模块壳,是为公道放置模块在编译产物中的位置而存在的,本身不具备模块的意义,所以不能共享,仅能在App应用内使用,依赖于这些模块壳的模块也无法在应用间共享。
上述的模型中通过HSP将HAR包公道地分配到编译产物中,使每个HAR包在App编译产物中仅存在一份,从而达到App Size最小,而模块壳不能过多,否则大概会影响安装速度和启动性能。
这两种模型都是理想模型,更多的业务模型是两者的平衡态或者两种模型的组合体,比如某个共享库本身代码和资源比较少,占用的空间不大,例如打印日志模块,那么将该模块编译进所有的编译产物中,增大的App Size比较少,同时性能会相对好一些。
不包罗公共能力模块
一般这种应用比较少,纵然有的话也是一些小型应用,可以参考单HAP的场景。
总结
应用开辟者需要根据自身技能架构选择适合的工程模块化模型,工程模块化模型也不是一成稳定的,需要根据业务和技能架构的演进而演进。根据诉求在HAP、HAR和HSP三种范例中进行选择使用。
对于具备独立运行和安装的模块只能选择HAP包,并将其作为Feature范例的HAP存在于App中;对于不具备独立特性部分,用户使用频率较少的模块,将其做成HSP按需加载模块存在于App中。对于需要共享的模块,只能采用HAR包,将其通过OHPM仓共享给其他工程使用。而HAR是静态共享库,在多HAP或者按需加载场景下,在编译后大概会在物理上存在多份,所以需要公道采用公共HSP模块壳,使App Size最小化。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
本帖子中包含更多资源
您需要
登录
才可以下载或查看,没有账号?
立即注册
x
回复
举报
0 个回复
倒序浏览
返回列表
快速回复
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
or
立即注册
本版积分规则
发表回复
回帖并转播
回帖后跳转到最后一页
发新帖
回复
北冰洋以北
论坛元老
这个人很懒什么都没写!
楼主热帖
超融合,变了?
一零零七、Docker快速入门
Linux基础篇(6)---》常用命令大全(网络 ...
鸿蒙最新功能及承载设备详解:HarmonyO ...
作为开发人员,您应该熟悉的 7 个 Java ...
代码审计(Java)——WebGoat_Authentica ...
Kubernetes-namespace
如何快速而优雅的解决问题(提问的智慧 ...
Unity的AssetPostprocessor之Model之动 ...
零代码,让业务人员实现应用创造自由 ...
标签云
运维
CIO
存储
服务器
快速回复
返回顶部
返回列表