文章目录
- [工业制造领域中的 AAA 架构:是什么、为什么用、有哪些代价,以及如何避免过度设计](#工业制造领域中的 AAA 架构:是什么、为什么用、有哪些代价,以及如何避免过度设计)
-
- 一、工业制造为什么容易走向复杂架构
-
- [1. 异构系统非常多](#1. 异构系统非常多)
- [2. 设备接入复杂且变化频繁](#2. 设备接入复杂且变化频繁)
- [3. 业务规则并不简单](#3. 业务规则并不简单)
- [4. 对稳定性和可追溯要求很高](#4. 对稳定性和可追溯要求很高)
- [二、什么是工业制造领域中的 AAA 架构](#二、什么是工业制造领域中的 AAA 架构)
-
- [1. A1:Application Layer(应用层)](#1. A1:Application Layer(应用层))
- [2. A2:Abstraction / Architecture / Domain Layer(抽象/领域层)](#2. A2:Abstraction / Architecture / Domain Layer(抽象/领域层))
- [3. A3:Adapter / Access Layer(适配/接入层)](#3. A3:Adapter / Access Layer(适配/接入层))
- [三、AAA 架构在工业制造中的一个直观例子](#三、AAA 架构在工业制造中的一个直观例子)
- [四、AAA 架构的主要优点](#四、AAA 架构的主要优点)
-
- [1. 降低系统耦合度](#1. 降低系统耦合度)
- [2. 更适合应对异构集成](#2. 更适合应对异构集成)
- [3. 提高可维护性](#3. 提高可维护性)
- [4. 更利于复用](#4. 更利于复用)
- [5. 更方便分阶段演进](#5. 更方便分阶段演进)
- [6. 有助于测试](#6. 有助于测试)
- [五、AAA 架构的主要缺点](#五、AAA 架构的主要缺点)
-
- [1. 学习和理解成本高](#1. 学习和理解成本高)
- [2. 开发初期速度可能变慢](#2. 开发初期速度可能变慢)
- [3. 容易出现"为了架构而架构"](#3. 容易出现“为了架构而架构”)
- [4. 抽象过早会导致错误模型](#4. 抽象过早会导致错误模型)
- [5. 调试链路变长](#5. 调试链路变长)
- [6. 对团队工程能力要求更高](#6. 对团队工程能力要求更高)
- [六、工业制造场景下,AAA 最适合用在哪里](#六、工业制造场景下,AAA 最适合用在哪里)
-
- [1. 多系统集成明显的场景](#1. 多系统集成明显的场景)
- [2. 业务规则复杂且长期演进的场景](#2. 业务规则复杂且长期演进的场景)
- [3. 多工厂/多产线复制推广场景](#3. 多工厂/多产线复制推广场景)
- [4. 需要长期维护的核心系统](#4. 需要长期维护的核心系统)
- [七、哪些场景不适合一开始就上很重的 AAA](#七、哪些场景不适合一开始就上很重的 AAA)
-
- [1. 小型单体应用](#1. 小型单体应用)
- [2. 短期试点项目](#2. 短期试点项目)
- [3. 团队对业务理解还很浅](#3. 团队对业务理解还很浅)
- [4. 需求尚未稳定](#4. 需求尚未稳定)
- [八、如何避免 AAA 架构"用得过重"](#八、如何避免 AAA 架构“用得过重”)
-
- [1. 从真实变化点出发,而不是从理想分层出发](#1. 从真实变化点出发,而不是从理想分层出发)
- [2. 只为复杂部分建抽象,不为简单 CRUD 建抽象](#2. 只为复杂部分建抽象,不为简单 CRUD 建抽象)
- [3. 抽象层必须承载业务语义,不能只是转发层](#3. 抽象层必须承载业务语义,不能只是转发层)
- [4. 不要过早追求"大一统模型"](#4. 不要过早追求“大一统模型”)
- [5. 适配层可以统一接口,但不要掩盖关键差异](#5. 适配层可以统一接口,但不要掩盖关键差异)
- [6. 控制对象层级数量](#6. 控制对象层级数量)
- [7. 让架构服务于交付,而不是让交付迁就架构](#7. 让架构服务于交付,而不是让交付迁就架构)
- [8. 对核心规则做测试,对接入层做契约验证](#8. 对核心规则做测试,对接入层做契约验证)
- [9. 增强可观测性,否则分层越多越难排障](#9. 增强可观测性,否则分层越多越难排障)
- [10. 定期审查"空洞抽象"](#10. 定期审查“空洞抽象”)
- [九、一个更务实的落地方法:轻量 AAA](#九、一个更务实的落地方法:轻量 AAA)
- [十、一个判断标准:什么时候说明 AAA 已经过重了](#十、一个判断标准:什么时候说明 AAA 已经过重了)
- [十一、结语:工业制造的 AAA,重点不在"标准",而在"克制"](#十一、结语:工业制造的 AAA,重点不在“标准”,而在“克制”)
工业制造领域中的 AAA 架构:是什么、为什么用、有哪些代价,以及如何避免过度设计
在工业制造数字化建设中,企业经常会遇到这样的问题:
一边是设备、产线、工艺、质量、计划、仓储、供应链等复杂业务不断耦合;另一边是 MES、SCADA、ERP、WMS、QMS、PLM 等系统长期并存,数据流复杂,接口多、变化快、维护成本高。
在这种背景下,很多团队会引入一种分层清晰、职责明确的架构方式来组织系统,这类方式常被概括为 AAA 架构。在很多工业软件语境下,AAA 通常可以理解为:
- Application Layer(应用层)
- Architecture / Domain Abstraction Layer(架构/领域抽象层)
- Adapter / Access Layer(适配/接入层)
不同公司对 AAA 的命名可能略有差异,但其核心思想通常一致:
把业务编排、领域能力、外部系统/设备接入分开,让工业系统在复杂集成环境中更容易扩展和维护。
这篇文章会从工业制造场景出发,详细介绍 AAA 架构的含义、适用价值、优缺点,以及如何避免把它做成一个"看起来高级、实际上很重"的系统。
一、工业制造为什么容易走向复杂架构
在互联网场景里,很多系统的复杂性主要来自高并发和快速迭代;而在工业制造领域,复杂性往往来自另外几个方面:
1. 异构系统非常多
一个典型制造企业可能同时存在:
- ERP:管财务、采购、销售、主计划
- MES:管生产执行
- SCADA:管设备监控和数据采集
- WMS:管仓储物流
- QMS:管质量
- PLM:管产品研发和工艺变更
- APS:管高级排产
- EAM/CMMS:管设备资产和维修
这些系统往往不是同一时期建设,也不是同一家供应商提供,数据模型和接口风格差异极大。
2. 设备接入复杂且变化频繁
工业现场通常要接 PLC、传感器、仪表、机器人、数控机床、AGV、视觉设备等。
协议可能涉及 OPC UA、Modbus、MQTT、Socket、串口、厂商私有协议等。设备更新、产线改造、接口升级都很常见。
3. 业务规则并不简单
工业制造并不是简单的"增删改查"。它包含大量复杂规则:
- 工单拆分与合并
- 工艺路线切换
- 批次追溯
- 质量判定与放行
- 设备联锁条件
- 异常停机与补报工
- 物料齐套校验
- 多组织、多工厂、多车间差异
4. 对稳定性和可追溯要求很高
很多工业系统不是"偶尔出错可以稍后修复",而是直接影响产线节拍、质量合规甚至安全生产。
因此,系统不仅要能用,还要"稳定、可定位、可回放、可审计"。
也正因为这些特征,工业制造项目特别容易出现下面两种极端:
- 一种极端是没有架构:接口代码四处散落,需求一变全链路修改。
- 另一种极端是架构过重:分层太多、抽象太多、开发效率极低,团队逐渐被架构本身拖住。
AAA 架构通常就是在这两者之间寻找平衡的一种办法。
二、什么是工业制造领域中的 AAA 架构
虽然不同团队对 AAA 的解释不完全一致,但在工业项目里,更实用的理解方式是"三层职责拆分":
1. A1:Application Layer(应用层)
这一层主要负责:
- 面向用户或业务流程的用例编排
- 组织具体业务场景
- 调用领域服务完成任务
- 控制权限、事务边界、流程状态
- 向前端、API、调度任务暴露能力
它不直接处理设备协议,也不应该堆满底层 SQL 和接口细节。
它更像是"业务流程导演"。
例如:
- 创建工单并下发到产线
- 执行报工
- 触发首检流程
- 批次完工入库
- 设备异常后暂停工序流转
2. A2:Abstraction / Architecture / Domain Layer(抽象/领域层)
这是 AAA 中最关键的一层,也是最容易被误解的一层。
它的核心作用是:
- 抽象制造业务中的核心对象和规则
- 沉淀稳定的领域能力
- 隔离上层应用流程和下层设备/系统差异
- 提供统一的业务语义
这一层常见对象包括:
- 工单
- 工序
- 工艺路线
- 设备资源
- 生产批次
- 物料批次
- 质量检验单
- 设备事件
- 产量/良率/节拍等生产指标
这一层不应该只是"把数据库表包一层",更不是"写一堆空接口"。
真正有价值的抽象层,应该沉淀制造场景中那些相对稳定、跨系统复用的业务规则。
比如:
- 工单只有在物料、设备、工艺条件满足时才能开工
- 某类工序必须先过首检才能批量生产
- 不同设备虽然采集协议不同,但都能统一映射成"设备状态变更事件"
- 不同系统的报工来源最终统一成"生产执行记录"
3. A3:Adapter / Access Layer(适配/接入层)
这一层负责跟"外部世界"打交道,包括:
- 数据库访问
- 第三方系统接口调用
- 消息队列
- 文件交换
- 设备协议接入
- 外部 API / WebService / SDK
- 工业协议解析与映射
它的目标是把外部差异"吃掉",向上层提供相对稳定的访问方式。
例如:
- 把某 PLC 的寄存器数据转换成统一设备点位模型
- 把 ERP 的工单接口响应映射为内部生产订单对象
- 把不同品牌设备的停机信号统一成标准事件格式
- 对接 WMS 时屏蔽对方 API 的字段差异与鉴权方式
三、AAA 架构在工业制造中的一个直观例子
以"生产报工"场景为例。
没有明确分层时
代码可能会这样长:
- Controller 收到报工请求
- 直接查数据库
- 直接调用 MES 表
- 同时请求 ERP 接口
- 直接解析设备状态
- 顺手更新库存表
- 写一堆 if/else 判断异常
- 最后发消息给 QMS
这种写法短期很快,但后期会变成一团。
用 AAA 分层后
应用层做什么
- 接收"报工"请求
- 校验调用身份
- 开启事务
- 编排报工流程
- 调用领域服务
- 发布后续事件
抽象/领域层做什么
- 判断该工单是否允许报工
- 判断工序状态是否合法
- 计算合格数、报废数、在制变化
- 生成生产执行记录
- 形成统一的业务事件
适配层做什么
- 从设备采集系统获取当前设备状态
- 写入生产记录库
- 调 ERP / WMS / QMS 接口
- 发送 MQ 消息
- 处理不同来源数据格式差异
这样一来,报工规则改动时,通常改动集中在领域层;
接口变化时,通常集中在适配层;
流程增加审批、补录、重试逻辑时,主要在应用层变化。
这就是 AAA 架构在工业制造里真正的价值:
让"变化"落在该落的地方。
四、AAA 架构的主要优点
1. 降低系统耦合度
工业系统最怕"牵一发而动全身"。
通过分层,可以把设备接入变化、第三方接口变化、业务规则变化隔离开,避免任何一个点的小改动都引发全局连锁修改。
2. 更适合应对异构集成
工业现场的现实是:不同工厂、不同产线、不同设备供应商共存。
适配层可以承接这些复杂性,抽象层则把它们统一成内部业务语义,降低上层使用成本。
3. 提高可维护性
当系统运行几年之后,维护成本往往远高于首版开发成本。
AAA 架构的边界清晰后,新人更容易理解代码,问题定位也更直接:
- 设备接入问题看适配层
- 流程编排问题看应用层
- 业务规则问题看领域层
4. 更利于复用
工业项目中很多能力是可复用的:
- 工单状态机
- 设备状态映射
- 批次追溯模型
- 质量判定规则
- 通用事件模型
把这些沉淀在抽象层,比散落在各个项目页面、接口、脚本里更有长期价值。
5. 更方便分阶段演进
工业项目一般不是一次性建完的,而是逐期上线。
AAA 架构允许你先把关键场景抽象出来,后续逐步扩展,而不是每接一个系统就复制一份逻辑。
6. 有助于测试
如果分层得当,很多核心业务规则可以脱离界面、数据库、设备环境做单元测试或服务测试。
这在工业软件里非常重要,因为真实现场环境往往难以完整复现。
五、AAA 架构的主要缺点
说完优点,必须看代价。
在工业制造项目里,AAA 架构并不是天然正确,尤其在团队经验不足时,副作用会非常明显。
1. 学习和理解成本高
很多团队成员更习惯"接到需求就写接口、查表、调接口"。
引入 AAA 后,需要理解:
- 分层边界
- 领域模型
- 抽象方式
- 依赖方向
- 事件流转
这会带来明显的认知门槛。
2. 开发初期速度可能变慢
简单需求如果也严格走完整套分层,开发者会感觉"同样一个功能,代码写了三倍"。
尤其在 PoC、试点线、小型项目中,这种成本非常明显。
3. 容易出现"为了架构而架构"
这是最常见的问题。表现包括:
- 每个类都要定义接口
- 每个动作都要封一层 service
- 每种对象都要 DTO、VO、DO、BO、Entity 各一份
- 抽象层没有真正业务语义,只是机械转发
- 实际逻辑不复杂,却做成高度通用平台
结果是代码看起来"很规范",但真正写需求时非常笨重。
4. 抽象过早会导致错误模型
工业场景差异很大。
如果团队在还没理解业务的时候就试图做"大而全"的统一模型,往往会得到一个谁都不满意的抽象:
- 看起来统一
- 实际表达力不足
- 业务一细化就到处打补丁
5. 调试链路变长
一条业务请求可能要经过:
- Controller
- Application Service
- Domain Service
- Repository
- Adapter
- External Client
- Event Handler
如果日志和可观测性做得不好,定位问题会比"单层直写"更难。
6. 对团队工程能力要求更高
AAA 架构真正发挥作用,依赖的不只是代码分层,还包括:
- 一致的命名规范
- 清晰的模块边界
- 稳定的接口设计
- 良好的测试习惯
- 完整的日志与监控
如果这些基础能力不足,分层越多,混乱反而越大。
六、工业制造场景下,AAA 最适合用在哪里
并不是所有系统都值得上 AAA。
它更适合以下场景:
1. 多系统集成明显的场景
例如 MES 同时对接 ERP、WMS、QMS、SCADA、设备采集平台。
这种情况下,适配层价值非常高。
2. 业务规则复杂且长期演进的场景
例如离散制造、半导体、汽车零部件、电子装配、医药、食品等行业,往往有复杂工艺、批次管控、质量追溯需求。
这时抽象层能承接长期变化。
3. 多工厂/多产线复制推广场景
如果一个方案需要从 A 工厂复制到 B 工厂、C 工厂,且底层设备与外围系统存在差异,AAA 能帮助你把"共性"和"个性"拆开。
4. 需要长期维护的核心系统
核心生产执行系统通常生命周期长,后续需求持续多。
这类系统更值得做合理分层。
七、哪些场景不适合一开始就上很重的 AAA
1. 小型单体应用
如果只是一个简单的安灯记录、点检录入、看板展示工具,业务规则并不复杂,就没有必要一开始就做厚重抽象。
2. 短期试点项目
很多工业数字化项目会先做试点验证价值。
这时最重要的是快速验证流程闭环,而不是先建立一套宏大的架构。
3. 团队对业务理解还很浅
如果连工艺流程、数据责任边界、异常处理逻辑都没搞清楚,过早抽象基本都会失败。
这时更应该先用相对直接的实现跑通,再逐步抽象稳定部分。
4. 需求尚未稳定
如果业务方连流程本身都在高频调整,过早设计复杂抽象层,往往很快失效。
八、如何避免 AAA 架构"用得过重"
这是工业项目里最关键的问题。
不是"要不要 AAA",而是"怎么用得刚好"。
下面给出一些实操原则。
1. 从真实变化点出发,而不是从理想分层出发
先问几个问题:
- 哪些外部系统最容易变化?
- 哪些设备协议差异最大?
- 哪些业务规则最复杂、最容易反复修改?
- 哪些能力会跨产线、跨工厂复用?
把真正高变化、高复用的地方抽出来。
不要一开始就把所有代码都"架构化"。
核心原则是:
先识别变化,再设计边界。
2. 只为复杂部分建抽象,不为简单 CRUD 建抽象
很多工业系统既有复杂流程,也有大量基础资料维护:
- 班次维护
- 设备台账维护
- 产线字典维护
- 代码表配置
- 角色权限设置
这些页面很多只是标准 CRUD。
如果也强行走完整的重量级领域抽象,会极大拖慢开发效率。
更合理的做法是:
- 复杂核心域:严格分层、明确抽象
- 简单支撑域:轻量实现、保持整洁即可
不是所有模块都要同样"重"。
3. 抽象层必须承载业务语义,不能只是转发层
一个常见反模式是:
- Controller 调 Application
- Application 调 Domain
- Domain 调 Repository
- 每一层只写一行转发代码
这种分层没有实际收益,只是在制造跳转成本。
真正值得保留的抽象层,至少要满足一个条件:
- 有稳定业务规则
- 有跨场景复用价值
- 有统一语义转换价值
- 有隔离外部差异的必要
否则,这层很可能只是"看起来高级"。
4. 不要过早追求"大一统模型"
工业制造差异非常大。
离散制造、流程制造、装配制造、半连续生产,对工单、批次、设备、工艺的理解可能都不同。
因此,不要一开始就试图设计一个覆盖所有行业、所有工厂的超级领域模型。
更实用的方法是:
- 先围绕当前核心业务做局部抽象
- 在真实复用中逐步收敛共性
- 通过边界上下文隔离差异
换句话说:
抽象要从具体中长出来,而不是从 PPT 中画出来。
5. 适配层可以统一接口,但不要掩盖关键差异
适配层的目的不是把所有设备、系统"硬揉成一样",而是:
- 在保留必要差异的前提下,提供稳定访问方式
- 统一共性字段和行为
- 显式暴露无法消除的差异
比如不同设备的状态定义本身不同,如果强行压成完全一样的枚举,可能会丢失现场语义。
这会让上层暂时"省事",却在后续分析和运维时制造更大问题。
6. 控制对象层级数量
工业软件里常见"对象爆炸":
- DTO
- Param
- Command
- Query
- Entity
- DO
- PO
- VO
- BO
- Event
- Result
并不是说这些对象一定不该有,而是要控制数量。
如果每次改一个字段都要改 7 个类,团队很快会失去维护意愿。
建议原则:
- 只有在边界清晰不同、职责确实不同的情况下再拆对象
- 小模块优先保持对象简洁
- 避免机械式一层一套对象
7. 让架构服务于交付,而不是让交付迁就架构
工业项目通常工期紧,且经常需要配合现场联调。
因此架构设计必须支持渐进实施:
- 先跑通主流程
- 再抽共性
- 再补测试和治理
- 再沉淀组件
不要要求所有模块从第一天开始就百分之百"标准化"。
更现实的方式是演进式治理。
8. 对核心规则做测试,对接入层做契约验证
为了防止 AAA 变复杂后难维护,测试策略要跟上。
建议:
- 领域层重点做规则测试
- 应用层做关键流程测试
- 适配层做接口契约测试、模拟测试
- 对关键设备/系统集成做少量端到端验证
这样能保证复杂度上升时,系统仍可控。
9. 增强可观测性,否则分层越多越难排障
工业现场排障效率很重要。
AAA 架构下至少要做好:
- 统一链路 ID
- 关键业务日志
- 外部接口调用日志
- 设备事件追踪
- 失败重试记录
- 业务状态变更审计
否则你会发现,虽然分层优雅了,但问题发生时没人知道卡在哪。
10. 定期审查"空洞抽象"
项目做久了,最容易积累一批"历史上为了扩展而保留、实际上没人用"的接口和抽象。
建议定期审查:
- 哪些接口只有一个实现且长期不会扩展
- 哪些抽象层只是简单透传
- 哪些通用模型反而让业务表达更困难
- 哪些适配器已经成为事实标准,不再需要额外包装
能收缩的地方就收缩。
架构不是越大越成熟,很多时候恰恰相反。
九、一个更务实的落地方法:轻量 AAA
如果你准备在工业制造项目里使用 AAA,我更建议采用"轻量 AAA"的思路,而不是一开始就全量铺开。
一个比较务实的做法是:
第一阶段:识别核心域
找出真正复杂、真正高变化的业务,例如:
- 工单执行
- 报工
- 质量放行
- 设备状态事件
- 批次追溯
只对这些核心流程做明确分层。
第二阶段:隔离外部接入
把 ERP、WMS、QMS、SCADA、设备协议接入统一收敛到适配层。
先解决最明显的耦合问题。
第三阶段:沉淀稳定领域能力
当你发现某些规则在多个场景重复出现,再把它们沉淀到抽象/领域层,而不是一开始就预设大量通用能力。
第四阶段:治理外围模块
对于基础资料、配置项、简单查询报表等外围模块,保持轻量,不必和核心域同等复杂。
这种方式的关键好处是:
把架构成本投入到最值得的地方。
十、一个判断标准:什么时候说明 AAA 已经过重了
如果你的项目出现以下现象,通常说明 AAA 用重了:
- 改一个字段要改很多层对象
- 简单需求开发周期明显过长
- 很多"抽象"没有实际复用
- 新人很难定位代码入口
- 业务方需求变化后,抽象层频繁被迫改造
- 团队讨论更多集中在分层形式,而不是业务问题
- 大量接口和基类存在,但真实实现很少
- 代码量增长很快,但交付效率没有提升
一套架构是否合适,不是看图画得多漂亮,而是看它是否真正降低了系统演进成本。
十一、结语:工业制造的 AAA,重点不在"标准",而在"克制"
工业制造领域天然复杂,因此合理的架构分层很有必要。
AAA 架构之所以常见,是因为它确实能帮助团队应对多系统集成、设备异构、业务规则复杂、长期演进这些现实问题。
但同样需要警惕的是:
工业软件的失败,很多时候不是因为没有架构,而是因为架构脱离了现场实际。
真正成熟的做法不是"把 AAA 做满",而是:
- 对复杂性保持敬畏
- 对抽象保持克制
- 对变化点保持敏感
- 对交付效率保持现实判断
归根到底,好的架构不是层数多,也不是术语多,
而是它能让你的系统在一年后、三年后、五年后,仍然改得动、查得清、接得上、跑得稳。
这才是工业制造架构设计真正应该追求的目标。