HarmonyOS NEXT 统一 ToolManager 架构插件化工具系统的设计与实现前言在 HarmonyExplorer 项目中工具箱模块集成了文件压缩、格式转换、哈希计算等多种实用工具。随着工具数量增长如何避免代码臃肿、实现工具的动态扩展成为架构设计的核心挑战。本文将详细讲解基于插件化理念的统一 ToolManager 架构设计实现新增工具零侵入式扩展。参考 ArkTS 接口定义规范 了解接口设计要点。一、ToolManager 架构设计理念1.1 传统工具管理的痛点在未引入 ToolManager 之前工具箱页面通过 if-else 或 switch-case 硬编码管理工具调用。这种方式存在以下问题问题影响严重程度新增工具需修改核心代码违反开闭原则高工具间无法统一管理维护成本高中工具历史记录分散数据不一致中工具间无法共享数据代码重复低1.2 插件化设计目标ToolManager 的设计目标是构建一个高内聚、低耦合的工具管理系统零侵入扩展新增工具只需实现接口并注册无需修改已有代码统一管理所有工具的发现、加载、执行、历史记录统一处理分类组织工具按类别管理支持动态分组展示生命周期管理工具的初始化、执行、销毁全程可控插件化架构的核心价值在于将变化隔离让系统在不修改稳定核心的前提下灵活扩展新能力。二、插件化接口设计 ITool2.1 ITool 接口定义所有工具必须实现 ITool 接口该接口定义了工具的生命周期方法和元数据。接口设计是整个架构的基石。exportenumToolCategory{FILEfile,IMAGEimage,MEDIAmedia,SECURITYsecurity,UTILutil}exportinterfaceToolResult{success:boolean;data:string;message:string;}exportinterfaceToolMetadata{id:string;name:string;description:string;category:ToolCategory;icon:Resource;isAvailable:boolean;}exportinterfaceITool{getMetadata():ToolMetadata;execute(input:string):PromiseToolResult;onActivate():void;onDeactivate():void;}2.2 抽象基类实现为了减少重复代码提供 AbstractTool 抽象基类子类只需关注核心执行逻辑exportabstractclassAbstractToolimplementsITool{protectedmetadata:ToolMetadata;constructor(metadata:ToolMetadata){this.metadatametadata;}getMetadata():ToolMetadata{returnthis.metadata;}abstractexecute(input:string):PromiseToolResult;onActivate():void{LogUtil.info(工具激活: this.metadata.name);}onDeactivate():void{LogUtil.info(工具停用: this.metadata.name);}}三、工具注册机制3.1 注册器设计ToolManager 内部维护一个工具注册表支持按 ID 和类别检索。注册采用 Map 结构保证 O(1) 查找效率。exportclassToolManager{privatestatictools:Mapstring,IToolnewMap();privatestaticcategoryIndex:MapToolCategory,ArraystringnewMap();staticregister(tool:ITool):void{constmetadata:ToolMetadatatool.getMetadata();this.tools.set(metadata.id,tool);this.addToCategoryIndex(metadata.category,metadata.id);LogUtil.info(工具注册成功: metadata.name);}staticunregister(toolId:string):void{consttool:ITool|undefinedthis.tools.get(toolId);if(tool!undefined){constmetadata:ToolMetadatatool.getMetadata();this.removeFromCategoryIndex(metadata.category,toolId);tool.onDeactivate();this.tools.delete(toolId);}}privatestaticaddToCategoryIndex(category:ToolCategory,toolId:string):void{letids:Arraystring|undefinedthis.categoryIndex.get(category);if(idsundefined){ids[];this.categoryIndex.set(category,ids);}ids.push(toolId);}privatestaticremoveFromCategoryIndex(category:ToolCategory,toolId:string):void{constids:Arraystring|undefinedthis.categoryIndex.get(category);if(ids!undefined){constindex:numberids.indexOf(toolId);if(index0){ids.splice(index,1);}}}}3.2 工具发现与加载工具注册在应用初始化时自动完成。通过 ToolRegistry 集中管理所有工具的注册调用exportclassToolRegistry{staticinitAllTools():void{ToolManager.register(newFileCompressTool());ToolManager.register(newFileHashTool());ToolManager.register(newImageConvertTool());ToolManager.register(newAudioConvertTool());ToolManager.register(newBase64Tool());LogUtil.info(所有工具注册完成);}}四、具体工具实现示例4.1 文件压缩工具以下展示一个完整的工具实现继承 AbstractTool 并实现 execute 方法exportclassFileCompressToolextendsAbstractTool{constructor(){super({id:tool_file_compress,name:文件压缩,description:支持 ZIP 格式文件压缩,category:ToolCategory.FILE,icon:$r(app.media.ic_tool_compress),isAvailable:true});}asyncexecute(input:string):PromiseToolResult{try{consttargetPath:stringinput.zip;constsuccess:booleanawaitZipManager.compressFiles(input,targetPath);return{success:success,data:targetPath,message:success?压缩成功:压缩失败};}catch(error){return{success:false,data:,message:压缩异常: error.message};}}}4.2 文件哈希工具exportclassFileHashToolextendsAbstractTool{constructor(){super({id:tool_file_hash,name:文件哈希,description:计算文件 MD5/SHA256 值,category:ToolCategory.SECURITY,icon:$r(app.media.ic_tool_hash),isAvailable:true});}asyncexecute(input:string):PromiseToolResult{consthashValue:stringawaitHashUtil.calculateFileHash(input,SHA-256);return{success:hashValue.length0,data:hashValue,message:哈希计算完成};}}图1ToolManager 插件化架构图展示接口层、注册层和工具实现层的关系五、ToolHistory 历史记录5.1 历史记录模型每次工具执行后自动记录历史方便用户查看和复用。ToolHistory 数据模型如下exportinterfaceToolHistory{id:string;toolName:string;content:string;createTime:number;}5.2 历史记录管理importdataPreferencesfromohos.data.preferences;exportclassToolHistoryRepository{privatestaticpreference:dataPreferences.Preferences|nullnull;privatestaticreadonlyMAX_HISTORY:number100;staticasyncinit(context:Context):Promisevoid{this.preferenceawaitdataPreferences.getPreferences(context,tool_history);}staticasyncaddHistory(history:ToolHistory):Promisevoid{if(this.preferencenull){return;}constkey:stringhistory_history.id;awaitthis.preference.put(key,JSON.stringify(history));awaitthis.preference.flush();}staticasyncgetHistoryList():PromiseArrayToolHistory{if(this.preferencenull){return[];}constall:Recordstring,objectawaitthis.preference.getAll();constlist:ArrayToolHistory[];constkeys:ArraystringObject.keys(all);for(constkeyofkeys){if(key.startsWith(history_)){consthistory:ToolHistoryJSON.parse(String(all[key]));list.push(history);}}list.sort((a:ToolHistory,b:ToolHistory)b.createTime-a.createTime);returnlist;}}六、工具分类管理6.1 分类索引查询ToolManager 提供按类别查询工具的能力Toolbox 页面据此进行分组展示。HarmonyExplorer 中预定义的工具分类如下分类枚举分类名称典型工具示例FILE文件工具文件压缩、文件哈希IMAGE图片工具图片格式转换、图片压缩MEDIA媒体工具音频转换、视频提取SECURITY安全工具文件加密、哈希校验UTIL实用工具二维码生成、Base64 编码exportclassToolManager{staticgetToolsByCategory(category:ToolCategory):ArrayITool{constids:Arraystring|undefinedthis.categoryIndex.get(category);constresult:ArrayITool[];if(ids!undefined){for(constidofids){consttool:ITool|undefinedthis.tools.get(id);if(tool!undefinedtool.getMetadata().isAvailable){result.push(tool);}}}returnresult;}staticgetAllCategories():ArrayToolCategory{returnArray.from(this.categoryIndex.keys());}staticasyncexecuteTool(toolId:string,input:string):PromiseToolResult{consttool:ITool|undefinedthis.tools.get(toolId);if(toolundefined){return{success:false,data:,message:工具不存在};}tool.onActivate();constresult:ToolResultawaittool.execute(input);constmetadata:ToolMetadatatool.getMetadata();awaitToolHistoryRepository.addHistory({id:Date.now().toString(),toolName:metadata.name,content:result.data,createTime:Date.now()});tool.onDeactivate();returnresult;}}七、ToolCard 组件适配7.1 组件设计ToolCard 是工具箱页面的展示组件直接消费 ToolMetadata 渲染工具卡片。参考 ArkUI 组件开发。7.2 ToolCard 实现Componentexportstruct ToolCard{Propmetadata:ToolMetadata;onToolClick:(toolId:string)void(){};build():void{Column(){Image(this.metadata.icon).width(40).height(40).margin({bottom:8})Text(this.metadata.name).fontSize(13).fontColor($r(app.color.text_primary)).maxLines(1)Text(this.metadata.description).fontSize(11).fontColor($r(app.color.text_secondary)).maxLines(2).margin({top:2})}.width(100%).padding(12).borderRadius(12).backgroundColor($r(app.color.bg_card)).alignItems(HorizontalAlign.Center).opacity(this.metadata.isAvailable?1.0:0.4).onClick((){if(this.metadata.isAvailable){this.onToolClick(this.metadata.id);}})}}八、工具间数据传递8.1 数据传递机制某些工具的输出可以作为另一个工具的输入例如哈希计算结果可以传递给 Base64 编码工具。ToolManager 提供 ToolContext 管理工具间数据流exportclassToolContext{privatestaticdataMap:Mapstring,stringnewMap();staticsetData(key:string,value:string):void{this.dataMap.set(key,value);}staticgetData(key:string):string{returnthis.dataMap.get(key)??;}staticclearData(key:string):void{this.dataMap.delete(key);}staticclearAll():void{this.dataMap.clear();}}工具间数据传递采用键值对存储模式解耦了工具之间的直接依赖任何工具都可以生产或消费数据。九、ToolManager 与 KitManager 协作9.1 职责边界ToolManager 管理工具的注册与执行流程KitManager 管理 HarmonyOS Kit 的能力封装。两者协作关系如下工具执行时通过 ToolManager 调度工具内部调用 KitManager 获取系统能力KitManager 封装 File Kit、Image Kit 等底层 APIToolManager 记录执行历史KitManager 不感知业务逻辑维度ToolManagerKitManager职责工具生命周期管理系统能力封装依赖方向调用 KitManager不依赖 ToolManager扩展方式注册新 ITool封装新 Kit数据管理ToolHistory无状态9.2 协作示例exportclassImageConvertToolextendsAbstractTool{constructor(){super({id:tool_image_convert,name:图片格式转换,description:支持 PNG/JPEG/WebP 互转,category:ToolCategory.IMAGE,icon:$r(app.media.ic_tool_convert),isAvailable:true});}asyncexecute(input:string):PromiseToolResult{constparams:ConvertParams{sourcePath:input,targetFormat:ImageFormat.JPEG,quality:90};constresult:ConvertResultawaitKitManager.getImageKit().convertFormat(params);return{success:result.success,data:result.outputPath,message:result.message};}}十、新增工具流程10.1 零侵入扩展步骤新增一个工具的完整流程如下创建工具类继承 AbstractTool实现 execute 方法编写核心逻辑在 ToolRegistry.initAllTools 中添加注册调用无需修改 Toolbox 页面、ToolCard 组件等已有代码// 步骤1-2: 创建新工具exportclassQrCodeToolextendsAbstractTool{constructor(){super({id:tool_qrcode,name:二维码生成,description:将文本生成二维码图片,category:ToolCategory.UTIL,icon:$r(app.media.ic_tool_qrcode),isAvailable:true});}asyncexecute(input:string):PromiseToolResult{constqrPath:stringawaitQrCodeUtil.generate(input);return{success:qrPath.length0,data:qrPath,message:二维码生成成功};}}// 步骤3: 在 ToolRegistry.initAllTools 中添加一行注册ToolManager.register(newQrCodeTool());// 新增一行即可整个新增工具过程只需编写一个新类和一行注册代码完全不影响已有功能体现了开闭原则的工程实践。总结统一 ToolManager 架构是 HarmonyExplorer 项目中插件化设计的核心实践。通过 ITool 接口定义、AbstractTool 基类复用、注册表机制和分类索引实现了工具的零侵入式扩展。ToolHistory 历史记录和 ToolContext 数据传递机制进一步增强了工具系统的实用性。与 KitManager 的分层协作确保了业务逻辑与系统能力的清晰边界。这一架构使得工具箱模块可以持续扩展而不会导致代码腐化。更多架构设计参考请查阅 HarmonyOS 应用架构指南 和 ArkTS 编程规范。如果这篇文章对你有帮助欢迎点赞、收藏⭐、关注你的支持是我持续创作的动力相关资源HarmonyOS 官方文档ArkTS 接口与抽象类ArkUI 组件开发指南Preferences 数据存储CSDN HarmonyOS 架构设计HarmonyOS 开源社区