知识卡片

防御性的本质:应对不确定性,边界是冲突的高发地

结构图卡

内容

不确定性源于我们对复杂系统的无知——不论用哪些维度或模型去观察描述一个系统,都无法完全覆盖它的所有方面。软件系统同样运行在充满不确定性的世界里:不管前期规划多完美、架构设计多合理、测试多全面,上线后依然会出现Bug——这些Bug本质上就是不确定性事件。防御性的作用,就是让我们承认系统运行中存在这种不确定性,并在意外事件发生时尽量把影响降到最低。冲突最容易发生的地方是边界——不分空间、物种、类型,只要存在实在的或虚拟的边界,就可能发生冲突。现实世界应对边界冲突有三种方法:阻断——在边界上把双方完全隔离(长城、石墙,建筑物功能区之间的隔离带);协议——双方约定何时、何种情况下不因边界上发生的事而冲突(国与国、企业与企业、人与人之间常见的约定手段);第三方仲裁——当冲突双方无法通过谈判或对抗解决问题时,引入第三方裁决。程序是一种”软”的边界,处理起来更灵活,但同样最容易在边界上出问题,而现实世界这三种防范思路可以直接映射到防御性编程的具体方法上。可迁移启发:诊断一个系统的薄弱点时,优先去检查各个模块/服务/团队交接的”边界”位置——凡是两个不同职责、不同团队、不同技术栈的东西交汇的地方,往往就是Bug和意外事件最集中爆发的地方,而不是任何一方内部逻辑最复杂的地方。

结构图

flowchart TB
  U["不确定性=对复杂系统的无知<br/>(即便规划测试完善,上线后仍有Bug)"]
  U --> B["冲突高发地=边界<br/>(不分空间/物种/类型)"]
  B --> M1["方法1:阻断(完全隔离,如长城/防火隔离带)"]
  B --> M2["方法2:协议(约定何时不冲突,如国际条约)"]
  B --> M3["方法3:第三方仲裁(谈判失败后引入裁决)"]
  M1 -.映射.-> P["防御性编程六法(见后续卡片)"]
  M2 -.映射.-> P
  M3 -.映射.-> P

参考来源

- 位置:《架构师启示录:知识模型、落地方法与思维模式》第8章《系统实现》之"8.3.1 防御性是什么"与"8.3.2 冲突发生的地方:边界"(源文件:_epub-src/EPUB/xhtml/chapter12.xhtml) - 结论依据:原文说明"不确定性源于我们对复杂系统的无知……防御性的作用就是使我们认识到系统运行中存在的不确定性,并在发生意外事件时尽量将其影响降至最低……边界的冲突不分空间、物种、类型。只要存在实在的或虚拟的边界,就可能发生冲突", 直接支撑本卡关于防御性本质及边界冲突三种防范原型的结构图。 - 原始内容:程序是一种"软"的边界,处理起来会更加灵活。