跨端架构解剖:小程序与PC共用核心引擎

在多端开发中,重复编写业务逻辑不仅增加维护成本,更易导致数据不同步。本文解析如何通过剥离渲染层与核心计算,实现测评引擎在跨端架构下的绝对复用。

在多端应用开发中,面对微信小程序与 Web PC 端的双线并行需求,一种常见的做法是分别维护两套代码。然而,当业务复杂度上升,尤其是涉及严谨的心理测评引擎时,题目跳转规则、算分逻辑、作答状态等核心业务的重复编写,极易导致多端状态不一致,且后期维护成本呈指数级上升。橙星云技术团队在设计跨端测评架构时,摒弃了“翻译代码”的思路,转而采用核心逻辑下沉的策略,通过剥离渲染层与业务层,实现了测评引擎在小程序与 PC 端的完全共用。这种架构设计不仅使得代码库更易于维护,也为后续接入 App 端或 H5 端奠定了坚实的技术基础。

状态管理与渲染层的硬隔离

要实现核心逻辑的跨端复用,最关键的一步是切断业务代码与宿主环境(浏览器 DOM 或小程序 Page)的直接耦合。无论是在 Vue、React 还是小程序原生框架中,UI 层仅仅是对底层数据状态的反映。过去由于前端逻辑与视图天然交织,开发者习惯于在组件内部直接进行数据加工与请求处理。

在架构层面,我们将系统划分为渲染视图层、跨端适配层和核心计算引擎层。核心引擎使用纯 JavaScript/TypeScript 编写,完全不依赖 window、document 或 wx 等特定环境的全局变量。它仅负责接收标准化的输入(如用户点击了某个选项的 ID,或是触发了倒计时事件),并输出当前的状态(如进度条比例、下一题数据、是否完成作答)。

这种硬隔离设计要求状态管理不能依赖于具体的框架(如 Vuex 或 Redux)。我们通过在核心层实现一套轻量级的发布订阅模式(Pub-Sub),让框架去监听引擎的状态变化。当小程序端或 PC 端的 UI 组件挂载时,只需订阅核心引擎的状态流。用户的每一次点击操作,都转化为标准的指令(Action)发送至引擎,引擎处理完状态转移后触发更新事件,UI 层被动重绘。两端各自只负责如何把数据画出来,而核心计算全权交由单一的引擎处理。

测评流转引擎的抽象设计

测评系统有其特殊的业务复杂度,尤其是跳题逻辑(根据上一题的选项决定下一题)和量表维度的实时积分。某些高级量表甚至需要基于历史所有答卷的选项矩阵来进行组合运算。如果将这些逻辑散落在组件内部,跨端复用便无从谈起。

我们在核心计算引擎中抽象出了一个有限状态机(FSM)来管理测评流转。状态机维护着当前的节点(题号)、用户已收集的作答记录栈、以及量表的规则解析器。当收到“提交选项”的指令时,引擎内部会触发状态转换。规则解析器会读取预先定义的结构化量表规则,执行条件判断计算,精确算出下一跳的目标节点。

为了应对极其复杂的跳转与多维度计分,我们将规则解析器设计为一个规则树遍历算法。无论是单选、多选还是量表题,其计分权重和跳转条件都被编译为抽象语法树(AST)。PC 端和小程序端在初始化时,均通过接口拉取同一份编译好的规则文件注入到引擎中。这种设计不仅保证了两端测评逻辑的绝对一致,更使得题库的更新可以完全动态化。后台一旦调整了题目规则,小程序和 PC 端无需重新发版,引擎拉取新规则后即可按照新的逻辑平稳运转。

跨端缓存与网络层的依赖反转

核心引擎虽然不依赖 UI 框架,但不可避免地需要进行网络请求和本地存储(如保存作答进度以防网络中断导致数据丢失)。小程序环境要求使用专属 API 接口及同步存储,而 PC 端更多依赖于原生 fetch 和 localStorage 等浏览器特性。

直接在核心层调用这些宿主 API 会彻底破坏其平台无关性。为此,我们引入依赖反转原则(Dependency Inversion Principle),在引擎内部仅定义存储和网络的接口契约(Interface)。在多端项目打包初始化时,由各端的适配层(Adapter)来实现这些接口并将其注入到引擎中。

例如,引擎需要持久化当前的作答快照,它只会调用抽象的存储方法,并不关心数据存放在哪里。在 PC 端工程中,适配层将其映射到 IndexedDB 或 localStorage;而在小程序工程中,适配层则代理给客户端的异步缓存 API。同样地,网络请求也通过 HTTP 代理层转发,适配层会负责补充 Header 头、处理鉴权 Token 等环境特有逻辑。这样一来,核心引擎就如同一个封闭的黑盒,通过标准化的接口与外部环境通信。它不需要知道自己正运行在哪个宿主容器中,只需专注于处理并发的缓存状态同步与防抖重试逻辑,确保用户在任何一端作答时,数据都能稳妥落地。

模块打包与工程化集成

在代码组织与工程化落地上,纯逻辑的抽象必然需要现代构建工具的配合。我们采用 Monorepo 模式来管理整个跨端项目。仓库被清晰划分为核心逻辑层模块和各端独立的项目应用,实现了物理层面的代码隔离。

核心模块配置了独立且严谨的构建流程,使用现代打包工具将其构建为通用的模块格式。在打包过程中,通过 Tree Shaking 静态分析去除无用代码,确保输出体积足够精简,以满足移动端及小程序对代码包体积的严苛限制。

两端的应用项目通过包管理器引用机制引入核心引擎模块。在构建小程序时,构建工具会将引用的引擎代码一并编译压缩至运行库中;而在构建 PC 端 Web 项目时,则直接参与工程的模块依赖图构建。整个开发工作流中,开发人员可以在核心层编写代码,并通过自动化的单元测试快速验证每一条跳转规则和计分逻辑,随后这些底层变更会无缝辐射至所有关联端,实现了核心业务的高度收敛与工程层面的可控。

Leave a Reply

Your email address will not be published. Required fields are marked *