接口是定义模块间通信规则的协议蓝图,明确输入输出、错误处理与状态语义;需剥离实现细节、统一错误枚举、显式分版本共存,并通过集中导出、契约测试等确保落地。

接口不是通信管道本身,而是定义管道该怎么用的图纸。它不传输数据,但决定了谁可以接、怎么接、传什么、错时怎么退——真正的灵活性来自契约的清晰性与约束力的平衡。
接口即通信协议蓝图
模块之间不直接连通,而是通过接口约定“管道”的口径、流向和信号规则。比如一个 MotorControl 接口,不是在写驱动代码,而是在画一张说明书:
- 输入端口有哪些参数?每个参数代表物理动作还是业务意图(如
angleDeg是目标角度,不是 PWM 占空比) - 输出是返回值、回调,还是状态变更事件?成功是否意味着电机已到位,还是仅指令已下发?
- 超时、断连、校验失败时,行为是否确定?是抛异常、返回错误码,还是静默降级?
让不同模块能“插上就用”的关键设计
接口要支持模块热插拔,核心是剥离实现痕迹,只保留可协商的业务语义:
- 用
startCalibration(CalibrationMode)替代sendCommand(0x05, [0x01])—— 消费方不用查芯片手册 - 错误统一用
enum MotorError { OVERHEAT, TIMEOUT, INVALID_ANGLE },不传 magic number 或字符串 - 状态查询走
getMotorStatus(): MotorStatus,而不是暴露寄存器地址或缓冲区指针 - 所有跨模块数据结构(如
MotorStatus)必须定义为export interface,且字段名体现业务含义(isMoving而非flag_bit2)
版本演进不撕裂通信链路
接口一旦发布,就不该靠加默认参数来“兼容”。真正可持续的灵活性来自显式分版与共存能力:
- 旧接口保持冻结,标注
@Deprecated并指向新接口 - 新增需求走全新接口(如
MotorControlV2),定义更细粒度动作或更强健的错误处理 - 通过依赖注入或服务注册机制(如 HarmonyNext 的
ServiceManager),让 V1 和 V2 实现并存于系统中 - 调用方按需选择绑定版本,避免“一半认 V1、一半认 V2”的协议混乱
契约落地才真正生效
接口定义再好,不被消费方实际导入使用,就只是文档。保障落地的关键动作:
- 所有对外接口必须从模块的
index.ts或等价入口集中导出,禁止“内部定义、外部复制” - 禁止在接口中引用私有类型(如
internalConfig: PrivateOptions) - 无 TypeScript 环境时,提供 JSON Schema 或 OpenAPI 描述,作为机器可读的等价契约
- 配套做契约测试(Contract Test):验证提供方是否真按接口语义行为,消费方是否真按接口假设调用

















