HarmonyOS掌上记账APP开发实践第53篇:领域组件设计模式:bill_base 与 asset_base 的领域驱动设计

发布时间:2026/7/21 2:53:22
HarmonyOS掌上记账APP开发实践第53篇:领域组件设计模式:bill_base 与 asset_base 的领域驱动设计
053 — 领域组件设计模式bill_base 与 asset_base 的领域驱动设计简介在传统 MVC 架构中业务逻辑和 UI 代码往往混杂在一起导致代码难以复用和测试。MoneyTrack 引入了领域驱动设计DDD思想将核心业务逻辑抽取到领域基础包bill_base和asset_base中。这些基础包遵循无 UI 纯逻辑的原则只包含 Enums枚举、Types类型定义和 Models数据模型三部分不依赖任何 UI 框架。这种设计让同一套业务逻辑可以被不同 UI 组件复用也大幅简化了单元测试——测试领域包不需要搭建 UI 环境。核心知识点1. DDD 领域驱动设计DDD 将应用按业务领域拆分为独立的限界上下文bill_base账单位领域包含账单类型枚举、账单状态、收支类别、账单查询参数。asset_base资产领域包含资产类型、资产账户模型、货币类型、资产统计聚合。每个领域包自治管理自己的数据结构和业务规则彼此之间通过 common 层的共享基类如BaseEntity实现低耦合的跨领域引用。2. 领域包的三层结构每一个领域基础包都严格遵循 Enums / Types / Models 三层架构asset_baseEnums/AssetType.ets资产类型枚举Types/AssetFilter.ets资产筛选接口Types/AssetReport.ets资产报表类型Enums/CurrencyType.ets货币类型枚举Models/AssetModel.ets资产数据模型Models/AssetCalculator.ets资产计算器bill_baseEnums/BillType.ets账单类型枚举Types/BillQueryParams.ets查询参数接口Types/BillSummary.ets统计摘要类型Enums/BillStatus.ets账单状态枚举Enums/CategoryType.ets收支类别枚举Models/BillModel.ets账数据模型Models/BillValidator.ets账单校验器Enums 层定义领域内所有的枚举常量。例如BillType.EXPENSE表示支出、AssetType.CASH表示现金资产。Types 层定义 TypeScript 接口和类型别名用于跨模块的数据传递约定。例如BillQueryParams定义了账单列表的筛选条件接口。Models 层定义数据模型类包含数据验证、格式化、业务计算等纯方法不涉及任何 UI 渲染。3. 领域包与 UI 包的分离原则领域包与 UI 包的分离是 DDD 在鸿蒙工程中落地的核心原则领域包bill_base / asset_base纯 ArkTS 代码零 UI 依赖可独立编译和测试。UI 包bill_card / asset_card包含 Component 声明依赖 UI 框架引用领域包的数据类型。分离的好处当 UI 框架升级或替换时领域逻辑不受影响同一套领域逻辑可以同时服务于多个 UI 组件。4. 跨领域引用虽然每个领域包独立自治但在实际业务中账单与资产存在自然的关联。跨领域引用通过 common 层的共享基类实现// common/lib-utils/src/main/ets/BaseEntity.etsexportabstractclassBaseEntity{id:string;createdAt:string;updatedAt:string;abstractvalidate():boolean;}// bill_base/Models/BillModel.etsimport{BaseEntity}frommoneytrack/lib-utils;exportclassBillModelextendsBaseEntity{amount:number;categoryId:string;assetId:string;// 关联资产ID通过 ID 引用而非直接引用 AssetModelvalidate():boolean{returnthis.amount0!!this.categoryId;}}这里的关键原则是通过 ID 引用而非对象引用——BillModel 持有 assetId 字段指向资产但不直接持有 AssetModel 对象从而避免 bill_base 对 asset_base 的强依赖。项目代码案例Enums/Types/Models 三层完整代码框架Enums/BillType.etsexportenumBillType{EXPENSEexpense,INCOMEincome,TRANSFERtransfer}Types/BillQueryParams.etsexportinterfaceBillQueryParams{type?:BillType;startDate?:string;endDate?:string;categoryIds?:string[];minAmount?:number;maxAmount?:number;keyword?:string;}Models/BillValidator.ets业务校验逻辑exportclassBillValidator{staticvalidateAmount(amount:number):string|null{if(amount0)return金额必须大于零;if(amount99999999.99)return金额超出上限;if(!/^\d(\.\d{1,2})?$/.test(String(amount)))return金额格式错误最多两位小数;returnnull;}staticvalidateBill(bill:BillModel):string[]{consterrors:string[][];constamountErrorthis.validateAmount(bill.amount);if(amountError)errors.push(amountError);if(!bill.categoryId)errors.push(请选择收支类别);if(!bill.assetId)errors.push(请选择关联资产);returnerrors;}}asset_base/Models/AssetModel.etsexportclassAssetModel{id:string;name:string;type:AssetType;balance:number;currency:string;formatBalance():string{return¥${this.balance.toFixed(2)};}isOverdrawn():boolean{returnthis.balance0;}}领域驱动设计的核心价值在于业务逻辑独立于 UI 框架、可复用、可测试为后续 6 个 UI 组件包的开发提供了稳固的基础。推荐参考文档领域驱动设计DDD基础组件化架构设计模式ArkTS 面向对象编程指南