知识卡片
模型还是代码:用三个问题判断业务逻辑该放在哪
内容
业务逻辑可以用流程建模语言表达,也可以用惯用编程语言表达——两个极端都不可取:只有一项任务、”所有魔法都在这里发生”的流程模型没有意义;纯图形化编程(历史上多次尝试过)也早已被证明行不通,普通编程语言在现代IDE上写代码更快、更高效、更易维护,模型塞太多细节既难维护又失去了图形化本该有的价值。经验法则是:把编程代码设为实现业务逻辑的默认选择,但有充分理由时该把某些逻辑放进流程模型——用三个问题来判断。一是”你需要在哪里(隐式地)停下”:如果流程要等待(人工处理、外部服务可用、消息到达等任何理由),就需要能安全存储状态,这正是工作流引擎的看家本领,但前提是相关任务本身是流程模型的一部分——这样才能在运维工具里看到实例卡在哪个任务、等太久了没有,工作流引擎是以任务粒度来”等待”的:如果一个任务的胶水代码里调用了两个远程服务,只有两个都成功才能继续;但如果拆成两个各自只调一个远程服务的任务,引擎就能记住其中一个已经成功、只需要重试另一个。二是”参与者需要定期讨论什么”:凡是需要和其他参与者定期讨论的内容都该放进图形模型(这条经验规则不绝对,比如复杂定价计算可能需要定期讨论却不适合塞进图形流程),对控制流而言尤其正确,因为不同参与者对具体业务细节的关注程度天差地别;同时无论模型里包含什么,都会产生审计数据,可用来构建关键效能指标(KPI)。三是”什么在跨越边界”:如果要调用的两个软件组件或服务无法处于同一个技术事务里,就该把这两次调用拆进各自独立的任务——这样工作流引擎才能分别重试失败的服务调用,开发者也能围绕一致性策略做调节(这个话题会在讨论自治边界隔离及集成挑战的章节展开)。一个具体演化案例:确认新用户接受与否,最初可以全用Java本地实现;一旦评分功能改成调用外部服务,就得直面REST通信和服务可用性问题——[[荒野大集成Ash的故事揭示的常见反模式]]的教训在此重现,这正是引入轻量级工作流引擎的最佳时机,最简单的做法是只加一个任务;等到”评分服务调用要计费”这类新的业务讨论出现,把验证和评分的顺序显式画进流程模型,能省去反复口头解释的成本,还能顺带获得”因数据无效被拒的比例”“因低分被拒的比例”这类流程统计。