问题的提出
在票务系统这类长期运行的业务系统中,最常见的后期抱怨不是"功能不够",而是"改不动":想接一个新渠道要排队三个月,想加一种票务规则要等发版,想换供应商接手却发现没有源码。
这种"被锁死"的状态,表面是商务问题,根子往往是架构与交付方式的问题。本文从技术角度拆解三个根因,并给出对应的架构解法。
根因一:渠道对接硬编码,牵一发动全身
很多早期票务系统把渠道对接逻辑直接写进业务主流程。每接一个 OTA(携程、同程、美团、抖音来客等),就要在主流程里加一段 if-else,渠道越多,主流程越臃肿,任何改动都容易引入回归缺陷。
架构解法:适配器 / 插件层
把渠道对接抽象为统一的适配器接口,每个渠道实现为一个独立插件:
```
interface IChannelAdapter {
submitOrder(order); // 下单
queryStock(skuId); // 查库存
verify(code); // 核销
cancel(orderId); // 退单
}
```
新增渠道 = 新增一个适配器实现,不改动主流程。主流程稳定,扩展点收敛。
根因二:票务规则写死在代码里,业务变更必须发版
票务规则(分时预约、计次票、年卡、套票、市民免费票、渠道隐藏票等)本质上是一组业务规则,但很多系统把它们硬编码在代码中。业务方每调整一次规则,研发就要改代码、测试、发版,响应周期长、风险高。
架构解法:规则可配置化
把票务规则抽象为可配置的模型,用表达式或规则引擎表达使用条件。例如用 Cron 表达式描述"在特定时间窗口内有效"的门票,用配置项描述"可使用 N 次 / 是否限当日 / 是否可退"。
规则可配置化之后,业务调整从"改代码"降级为"改配置",无需发版即可生效,这是长期可维护性的关键。
根因三:交付不完整,后续无法自主维护
只交付编译产物、不交付源码与文档,是"被锁死"最直接的原因。一旦供应商不再维护,系统就成为无人能修的孤岛。
架构解法:以"可自主维护"为交付目标
完整的交付物应当包括:
- 全部源代码;
- 数据库脚本与初始化数据;
- 部署文档与环境说明;
- 接口文档与数据字典。
验收标准不应停留在"功能可运行",而应包含"第三方团队可接管"。判断是否被锁死的终极问题只有一个:我能不能不通知原供应商,直接找另一个团队接手?
一套可落地的架构检查清单
检查项 | 达标标准
渠道对接 | 适配器/插件化,新增渠道不改主流程
票务规则 | 可配置表达,变更无需发版
硬件适配 | 设备协议抽象为驱动层,支持多种闸机/自助机
数据访问 | 统一数据模型 + 开放接口 + 批量导出
交付物 | 源码 + 脚本 + 部署文档 + 接口文档齐备
可交接性 | 第三方团队可仅凭交付物接管
小结
"二次开发被锁死"很少是单一原因,但技术上可以归结为三点:扩展点没有收敛、规则没有配置化、交付不够完整。
在设计阶段就把这三点处理好,系统的生命周期成本会显著下降,也不会在几年后陷入"想改改不动"的被动局面。
(本文为技术经验分享。)