用户云卷云舒 发表于 2024-10-28 19:06:45

鸿蒙原生APP开辟之应用架构设计(模块化设计)

往期推文看点



[*] 学鸿蒙开辟的优劣势,你清楚吗?建议你了解一下!
[*] 鸿蒙(HarmonyOS)北向开辟知识点记录~
[*] 鸿蒙(OpenHarmony)南向开辟保姆级知识点汇总~
[*] 鸿蒙应用开辟与鸿蒙体系开辟哪个更有远景?
[*] 嵌入式开辟适不适合做鸿蒙南向开辟?看完这篇你就了解了~
[*] 对于大前端开辟来说,转鸿蒙开辟究竟是福照旧祸?
[*] 鸿蒙岗位需求突增!移动端、PC端、IoT到底该怎么选?
[*] 记录一场鸿蒙开辟岗位面试经历~
[*] 一连更新中……
随着应用规模的扩大和业务需求的复杂化,代码的复杂度相应提升。因此,良好的应用架构设计变得尤为紧张,架构设计的目标是让应用更易于维护、扩展和测试。
开辟者在应用开辟过程中,经常面临以下寻衅:


[*]代码构造紊乱,模块间的耦合度高,导致一个模块的变动大概对其他模块产生影响,从而使代码难以维护。
[*]应用的扩展性差,新功能的添加往往须要对现有代码举行大量的修改。
为了办理这些题目,开辟者须要关注以下几个方面的架构设计:


[*]分层架构设计:将应用划分为产物定制层、基础特性层和公共本领层,可以降低层间的依赖性,从而提升代码的可维护性。通过分层架构设计进一步明白了每层的职责和层间的交互机制,为开辟者出现了一个清晰且结构化的开辟框架。
[*]模块化设计:将应用分解为多个功能模块,此中每个模块负责执行特定的功能。通过模块化设计提高了代码的可理解性和可复用性,使应用的扩展和维护变得更为简便,同时降低了体系各部门之间的耦合度。
模块化设计理念

在大型软件工程中,一般会伴随着多团队开辟,而各个团队之间,都是弱耦合交互,团队交付的业务之间以一种契约化形式的接口,定义了业务之间的接口,以此来满足各个团队的业务独立发展,互不影响,实现快速迭代演进,这就须要业务模块化。模块化是现代软件工程的焦点原则之一,它通过将大型的复杂体系拆解为更小、更容易管理和理解的部门——功能模块,来提高体系的可维护性和可拓展性。每个功能模块都是一个独立的单位,具有清晰定义的接口和职责,能够与其他模块交互以完成复杂的使命。
在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 多工程相助模式
https://img-blog.csdnimg.cn/img_convert/87ba17bb75c7ec6ec0cc11f2286eb17a.webp?x-oss-process=image/format,png
这部门可以发布到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包
https://img-blog.csdnimg.cn/img_convert/7757ff1cc830977a4efe4569d6b3e4bf.webp?x-oss-process=image/format,png
如上图所示,工程内存在三个模块,HAP包为应用主入口模块,HSP为应用主界面表现模块,HAR_COMMON集成了所有通用工具类,此中funcResult为func方法的执行效果。
由于HAP和HSP模块同时引用HAR_COMMON模块时会粉碎HAR的单例模式,所以HAP和HSP模块利用HAR_COMMON中的funcResult时,会导致func方法在两个模块加载时各执行一次,使得文件执行时间耗时增长。
假如仅从性能的角度思量,可以利用以下方式举行修改,从而到达缩短冷启动阶段耗时的目标。
图3 切换为HAP包和HAR包分别引用雷同HAR包
https://img-blog.csdnimg.cn/img_convert/5815ae752c062e6a445b302be2fcca70.webp?x-oss-process=image/format,png
   说明


[*]在多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包
https://img-blog.csdnimg.cn/img_convert/04af742a105bff87a5c0adc4572ff8c9.webp?x-oss-process=image/format,png
图5 优化后,利用HAR取代HSP
https://img-blog.csdnimg.cn/img_convert/3f728e5685a6d00be0c04c0948bb68cc.webp?x-oss-process=image/format,png
优化前后的对比数据如下:
方案阶段时长(毫秒)(优化前)利用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 非按需加载工程模型
https://img-blog.csdnimg.cn/img_convert/7a6b2b143f5929c61b79d849fff06b77.webp?x-oss-process=image/format,png
上图工程架构中,除了产物模块层中与装备相干的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模块壳承载
https://img-blog.csdnimg.cn/img_convert/1a191cddd5ef15d0bf7b48df733bb06a.webp?x-oss-process=image/format,png
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模块承载
https://img-blog.csdnimg.cn/img_convert/1609aaac9490cb317b6d4f3df0b99b60.webp?x-oss-process=image/format,png
因为公共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工程模块表示图
https://img-blog.csdnimg.cn/img_convert/1fd4258299aad3cf559d909c72a7fd1a.webp?x-oss-process=image/format,png
从编译产物上看,多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工程模块表示图
https://img-blog.csdnimg.cn/img_convert/d2cdf61410e60910d599eee2ace6998d.webp?x-oss-process=image/format,png
   说明
须要注意,在应用间共享的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最小化。
最后

经常有许多小同伴抱怨说:不知道学习鸿蒙开辟哪些技能?不知道须要重点把握哪些鸿蒙应用开辟知识点?
为了能够帮助到大家能够有规划的学习,这里特别整理了一套纯血版鸿蒙(HarmonyOS Next)全栈开辟技能的学习路线,包罗了鸿蒙开辟必把握的焦点知识要点,内容有(ArkTS、ArkUI开辟组件、Stage模型、多端部署、分布式应用开辟、WebGL、元服务、OpenHarmony多媒体技能、Napi组件、OpenHarmony内核、OpenHarmony驱动开辟、体系定制移植等等)鸿蒙(HarmonyOS NEXT)技能知识点。
https://i-blog.csdnimg.cn/direct/18cbd8425bc147a38fec85aaf3877e2b.png#pic_center
《鸿蒙 (Harmony OS)开辟学习手册》(共计892页):https://gitcode.com/HarmonyOS_MN/733GH/overview

如何快速入门?

1.基本概念
2.构建第一个ArkTS应用
3.……
https://i-blog.csdnimg.cn/direct/1b6e847ad28d4eb6b6156295b60b7591.png
鸿蒙开辟面试真题(含参考答案):

https://i-blog.csdnimg.cn/direct/bcc55a0ef295426f8d5362930584d022.png
《OpenHarmony源码解析》:



[*]搭建开辟情况
[*]Windows 开辟情况的搭建
[*]Ubuntu 开辟情况搭建
[*]Linux 与 Windows 之间的文件共享
[*]……
[*]体系架构分析
[*]构建子体系
[*]启动流程
[*]子体系
[*]分布式使命调治子体系
[*]分布式通信子体系
[*]驱动子体系
[*]……
https://img-blog.csdnimg.cn/img_convert/b2a7c0f56b33ef83d8199a6e53e443f2.png
OpenHarmony 装备开辟学习手册:https://gitcode.com/HarmonyOS_MN/733GH/overview

https://img-blog.csdnimg.cn/img_convert/35b4e458bb0a8a3bb1c75278c7493fd5.jpeg

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 鸿蒙原生APP开辟之应用架构设计(模块化设计)