第三章 系统架构规划:货架系统整体架构设计、模块划分原则、接口定义规范

做货架系统这么多年,我最大的体会是:架构设计决定了项目成败的80%。很多团队一上来就画图纸、算承重,结果做到一半发现模块之间打架,接口对不上,返工成本高得吓人。

我个人习惯,拿到需求后先花一周时间做架构规划。别急着动手,想清楚了再干,反而更快。

3.1 整体架构设计:从顶层到底层

货架系统说白了就是一个承载-存取-管理的闭环。我把它分成三个层次:

层级 核心功能 典型组件
应用层 人机交互、业务逻辑 WMS接口、扫码终端、看板系统
控制层 设备调度、状态监控 PLC控制器、传感器网络、电机驱动
执行层 物理承载、机械动作 立柱、横梁、导轨、货叉

你想想看,如果应用层直接去控制电机,那代码得多乱?我在项目中遇到过一家工厂,他们把扫码逻辑写进了PLC程序里,结果每次换产品型号都要改底层代码,维护成本直接翻倍。

架构原则:上层只依赖下层的接口,不依赖实现。控制层只告诉执行层「把货箱送到B3位置」,至于怎么送、走哪条路径,那是执行层自己的事。

3.2 模块划分原则:高内聚、低耦合

模块怎么切?我总结了四个字:职责单一。每个模块只做一件事,并且做好。

举个例子,一个典型的货架系统可以拆成这些模块:

  • 货位管理模块:负责货位的分配、释放、状态维护
  • 存取调度模块:负责任务排队、路径规划、冲突解决
  • 设备控制模块:负责电机启停、传感器读取、异常处理
  • 数据同步模块:负责与上层WMS/ERP的数据交换
  • 安全监控模块:负责超载检测、防撞保护、急停逻辑

嗯,这里要注意:不要为了复用而过度拆分。我曾经把一个货位管理模块拆成了「货位分配」和「货位释放」两个子模块,结果发现它们共享了80%的代码逻辑,反而增加了接口复杂度。后来我学乖了,模块粒度以「一个人能独立维护」为标准。

我的经验:模块之间的依赖关系画成有向图,确保没有循环依赖。如果A依赖B,B又依赖A,那这两个模块就该合并,或者引入一个中间层。

3.3 接口定义规范:稳定、清晰、可扩展

接口是模块之间的契约。契约定好了,各干各的,互不干扰。

我习惯用RESTful风格来定义接口,虽然货架系统是嵌入式环境,但接口设计的思想是通用的。

举个例子,存取调度模块对外暴露的接口:

// 请求格式
{
  "taskId": "TASK_20240301_001",
  "type": "store",        // store: 入库, retrieve: 出库
  "sku": "SKU_A001",
  "quantity": 10,
  "priority": 1           // 1-5, 1最高
}

// 响应格式
{
  "taskId": "TASK_20240301_001",
  "status": "accepted",   // accepted, queued, rejected
  "estimatedTime": 12.5,  // 秒
  "location": "A-03-12"   // 分配的货位
}

为什么要定义得这么细?因为接口一旦发布,改起来就是牵一发动全身。我在项目中遇到过最惨的一次,是接口返回的字段名从「location」改成了「binLocation」,结果下游三个系统全部要改,光联调就花了两周。

避坑指南:接口版本号一定要带上。我建议用URL路径版本号,比如 /api/v1/task,而不是请求头版本号。因为URL版本号更直观,调试时一眼就能看出来。

3.4 接口设计的三个关键点

第一,接口要幂等。同一个请求发两次,结果应该一样。比如入库任务,如果第一次成功了,第二次再发应该返回「已存在」而不是再执行一次。否则,网络重试时就会出大问题。

第二,接口要异步。货架系统的操作通常需要几秒到几十秒,不能阻塞调用方。我习惯的做法是:接口立即返回一个taskId,然后通过回调或轮询获取结果。

第三,接口要容错。输入参数校验要严格,但返回信息要友好。比如「quantity不能为负数」比「参数错误」有用得多。

接口属性 要求 反例
幂等性 重复请求不产生副作用 重复入库导致库存翻倍
异步性 立即返回,不阻塞 接口等待10秒才返回
容错性 输入校验+友好提示 直接抛500错误

3.5 架构文档:写清楚,更要画清楚

光有代码不够,文档必须跟上。我要求团队必须输出三张图:

  • 架构总览图:展示所有模块和它们之间的依赖关系
  • 时序图:展示一个典型任务的完整流程,比如「入库任务从WMS下发到货叉动作」
  • 接口清单表:列出所有接口的URL、请求格式、响应格式、错误码

文档不是写给别人看的,是写给自己看的。三个月后你回头改代码,没有文档,你连自己写的接口都记不清。

总结一下:架构规划是货架系统最值钱的部分。模块划分要职责单一,接口定义要稳定清晰,文档要跟上。前期多花一周,后期省下一个月。

下一章,我会讲货架系统的结构力学计算,那是真正考验数学功底的地方。到时候我会分享一个我踩过的坑——立柱截面选小了,结果货架装到一半发现变形了...嗯,那真是血的教训。