鸿蒙系统的三层架构设计主要包括公共能力层、基础特性层和产品定制层,这种分层设计有助于实现高内聚、低耦合的模块化开发,便于多设备适配和团队协作。鸿蒙一多开发的工程级一多就是通过三层架构实现的。
这里是模版仓库gitee地址:
hm_pfc_object: 这是一个使用har包+hap包+hsp包搭建的鸿蒙项目三层架构的模版,简单实用,拉取之后改改名字即可作为三层架构项目模版。
1、三层架构的组成
1. 公共能力层(Common Layer)
功能:提供整个应用共享的基础组件、工具类、公共配置等,如公共UI组件、数据管理、网络请求封装等。
包类型:通常编译为HAR包或HSP包,只可以被基础特性层和产品定制层依赖,不可以反向依赖。
特点:
高复用性:公共能力层的模块被多个功能模块频繁使用。
独立性:公共能力层的模块独立演进,不会因为其他层的变更而受到影响。
稳定性:公共能力层的模块通常比较稳定,变更频率较低。
2. 基础特性层(Features Layer)
功能:实现应用的各个功能模块,每个模块相对独立,可单独开发和测试。例如,首页模块、个人中心模块等。
包类型:通常编译为HAR包、HSP包或Feature类型的HAP包。
HAR包:适合工具库或公共能力,需要快速加载的场景。
HSP包:适合按需加载的场景,可以减少应用的初始包体积。
Feature类型的HAP包:适合需要单独部署或动态加载的模块。
特点:
模块化:每个功能模块独立开发和测试,便于团队协作。
灵活性:可以根据需求选择不同的包类型,优化性能和包体积。
可维护性:模块化设计提高了代码的可维护性。
3. 产品定制层(Product Layer)
功能:针对不同设备形态(如手机、平板等)进行功能和特性集成,是应用的主入口。
包类型:通常编译为Entry类型的HAP包,作为应用的主入口,不可以横向调用。
特点:
设备适配:根据设备类型(如手机、平板)定制应用的入口和功能。
主入口:产品定制层是应用的主入口,负责启动应用。
集成性:将基础特性层的模块集成到具体的产品中。
2、包的选择
hap、hsp和har包的区别:
包类型定义适用场景特点加载方式示例HAP包应用的安装包,包含应用的代码、资源和配置文件。应用主入口或动态特性模块,需要独立安装和运行的场景。独立安装和运行,支持按需下载安装,减少应用初始包的大小。安装到设备上应用的主入口模块,如手机应用的主页面。HSP包动态共享包,用于在运行时按需加载代码和资源。按需加载和共享代码的场景,多个模块需要共享同一份代码和资源。运行时按需加载,多个模块共享同一份代码,减少包体积。运行时加载功能模块不常用,需要按需加载,如应用的扩展功能。HAR包静态共享包,用于在编译时打包到引用方的包中。工具库或公共能力,需要快速加载的场景,模块需要独立演进。编译时打包到引用方的包中,加载效率高,独立演进。编译时打包工具库或公共能力,如网络请求封装、数据管理等。
公共能力层(commons):原本我使用的是一个har包,但是处于对缩小总包的考虑,换成了hsp包,公共能力层需要被其他所有包依赖,多个包引用同一个包,如果使用har包,就会在引用的包内拷贝一份资源,导致体积变大,所以对于多次引用的公共能力层,我推荐使用hsp包。
基础特性层(featrues):基础特性层,这里一般对应应用的几个大的模块,比如tab的内容,建议有几个tab栏就创建几个包,由于基础特性层只被产品定制层使用到,引用次数少,推荐使用加载性能更好的har包。
产品定制层(products):这里作为程序的入口,这里推荐使用可以独立打包的hap包
3、搭建三层架构
了解完了什么是三层架构,接下来就一步步搭建三层架构
产品定制层创建
先创建一个空工程,这里是创建hap包,也就是程序入口,产品定制层
然后在项目根目录下面创建三个文件目录 common features products ,同时将erntry模块移到products中
公共能力层创建
再创建basic模块,在common目录下 (公共能力层),basic是hsp包,要选择动态共享包创建
选择动态共享包,命名basic,建议直接命名为basic 点击完成
基础特性层创建
再是基础特性层在featrues目录下创建多个har包,包数量建议根据项目tab页面数量来确定,就以home首页模块为例:
选择静态共享包,命名为home,根据项目具体模块名称来
此处是以home模块为例的创建步骤,根据项目具体有多少模块就创建多少个包,此案例创建了四个模块,也就是四个har包
配置依赖
下一步就是配置依赖,配置依赖的目的是为了能构引用共享包中的资源,有一点需要注意,模块与模块之间不能循环依赖,否则会报错
在entry模块中配置对其他五个包的依赖
在entry模块下的oh-package.json5(products/entry/oh-package.json5)文件中配置依赖
依赖如下:
{
"name": "entry",
"version": "1.0.0",
"description": "Please describe the basic information.",
"main": "",
"author": "",
"license": "",
"dependencies": {
// 此处填写依赖包
"basic": "file:../../common/basic",
"home": "file:../../features/home",
"message": "file:../../features/message",
"mine": "file:../../features/mine",
"order": "file:../../features/order"
}
}
在基础特性层 featrues配置对common的依赖
在基础特性层 featrues 的四个模块下的oh-package.json5(features/home/oh-package.json5)文件中配置对basic的依赖 以home模块为例,其他三个模块同样步骤配置
依赖配置如下:
{
"name": "home",
"version": "1.0.0",
"description": "Please describe the basic information.",
"main": "Index.ets",
"author": "",
"license": "Apache-2.0",
"dependencies": {
// 此处填写依赖包
"basic": "file:../../common/basic"
}
}
配置好依赖之后可能需要重新打开项目,以防止依赖没有被识别到而报错
模块导出资源
common层下的资源导出
在common/basic/src/main/ets/components目录下创建一个index.ets文件统一管理导出的资源,创建一个BasicButton.ets写一个通用组件示例
BasicButton.ets通用组件内容
@Component
export struct BasicButton {
// 模块化组件
@Prop message: string = 'basic';
build() {
Button('我是basic模块的通用组件')
.backgroundColor('#F9713D')
.onClick(() => {
AlertDialog.show({ message: `我在${this.message}模块用到` })
})
}
}
index.ets中导出资源
export * from './BasicButton'
最后在common/basic/Index.ets 文件中统一导出所有basic中的资源
common/basic/Index.ets导出如下:
export * from '../basic/src/main/ets/components'
featrues层下的资源导出
这里还是以home模块为例,其他模块相同操作即可
在features/home/src/main/ets 目录下创建views目录,views目录下面创建homeView.ets编写ui页面,index.ets统一导出资源
homeView.ets中的简易页面
import { BasicButton } from 'basic'
@Component
export struct homeView {
build() {
Column({ space: 20 }) {
BasicButton({ message: 'home' })
Text("我是home模块")
.fontSize(40)
.fontWeight(FontWeight.Bold)
}
.justifyContent(FlexAlign.Center)
.backgroundColor('#ccc')
.width('100%')
.height('100%')
}
}
index.ets中统一导出
export * from './homeView'
最后在features/home/Index.ets 文件中统一导出所有home模块中的资源
Index.ets中的导出操作
export * from '../home/src/main/ets/views'
其他三个模块同理操作即可
导入资源并使用
在features层中使用common中的资源
以home模块中使用为例,其他三个模块同样操作即可
在homeView.ets中使用basic模块中的组件
import { BasicButton } from 'basic'; // 导入basic模块资源
@Component
export struct homeView {
build() {
Column({ space: 20 }) {
// 使用basic模块的组件
BasicButton({ message: 'home' })
Text("我是home模块")
.fontSize(40)
.fontWeight(FontWeight.Bold)
}
.justifyContent(FlexAlign.Center)
.backgroundColor('#ccc')
.width('100%')
.height('100%')
}
}
其他模块同理导入即可
在products层使用featrues层资源
示例在entry模块下创建了四个tab栏分别对应features中的四个模块,代码如下
import { homeView } from 'home'
import { messageView } from 'message'
import { mineView } from 'mine'
import { orderView } from 'order'
@Entry
@Component
struct Index {
build() {
Tabs() {
TabContent() {
homeView()
}.tabBar('首页')
TabContent() {
orderView()
}.tabBar('订单')
TabContent() {
messageView()
}.tabBar('消息')
TabContent() {
mineView()
}.tabBar('我的')
}
.barPosition(BarPosition.End)
.height('100%')
.width('100%')
}
}
4、效果展示
至此三层架构项目框架搭建完成,下面看效果:
entry中引用home模块页面,home页面中使用basic模块组件
entry中引用order模块页面,order页面中使用basic模块组件