知识卡片

变化与不变化的分离,及非功能性需求影响范围的分离

结构图卡

内容

任何代码——业务核心代码、非核心代码、技术类代码——都可以进一步拆成实体、规则、事件三部分:实体指对象或数据,规则指条件语句(if/else/while等),事件指要执行的功能。其中规则和数据是经常变化的部分,实体和功能则相对稳定,所以应该把规则和数据从相对稳定的部分里分离出来。规则又分业务规则(业务人员使用,运行中动态调整,常见做法是建立专门给业务人员用的参数管理中心)和技术规则(技术人员使用,比如数据库账密、第三方地址、线程数配置,通常放在配置文件或配置中心);数据方面,一般输入数据要通过对外暴露的参数传递,代码里用到的”魔法值”数据最好单独存放在专门的文件里、与其他代码分开。另一类重要的分离是”非功能性需求影响的部分”与其他部分的分离——比如秒杀活动中,购物功能需要高并发技术支持,物流功能则不需要,二者不该被绑在一起同等对待。这么做出于两个考虑:成本考虑(实现非功能性需求往往成本很高,应该把需要它的部分与其他部分分开,把实现范围限制在最小边界内);稳定性考虑(分离之后,即便其中一部分出问题,也不会因为绑定在一起而对其他功能造成连锁反应)。可迁移启发:审查一段代码里”经常改的东西”,先检查它是不是规则或数据——如果是,理应能在不碰核心业务逻辑代码的前提下单独调整(配置中心/参数管理中心);再检查系统里对高并发/高可用这类非功能性需求的实现范围,是不是精确圈定在真正需要它的那条链路上,而不是把整个系统一刀切地按最严苛的非功能性需求标准去设计——后者会白白抬高不需要这些能力的部分的成本和复杂度。

结构图

flowchart TB
  E["代码三部分:实体(稳定)/规则(易变)/事件(相对稳定)"]
  E --> R1["业务规则→参数管理中心(业务人员动态调整)"]
  E --> R2["技术规则→配置文件/配置中心"]
  E --> D["魔法值数据→单独文件存放"]
  N["非功能性需求影响范围分离<br/>(如秒杀购物需高并发,物流不需要)"]
  N --> N1["成本考虑:实现范围限制在最小边界"]
  N --> N2["稳定性考虑:避免绑定导致连锁故障"]

参考来源

- 位置:《架构师启示录:知识模型、落地方法与思维模式》第8章《系统实现》之"8.1.2 代码中的分离性"第3、4条(源文件:_epub-src/EPUB/xhtml/chapter12.xhtml) - 结论依据:原文说明"规则和数据属于经常变化的部分,而实体和功能则相对稳定。因此,应该将规则和数据分离出来……在秒杀活动中,购物功能需要秒杀技术支持,而物流并不需要……这种分离主要是出于两种考虑。一是出于成本考虑……二是出于稳定性考虑,分离之后即使其中一部分出现问题,功能之间也不会因为绑定在一起而出现连锁反应", 直接支撑本卡关于变化不变化分离及非功能性需求范围分离的结构图。 - 原始内容:代码执行过程中用到的一些魔法值数据最好单独存放在一个专门的文件中,与其他代码分开。