知识卡片

界面的四个有效条件,及规格由"下层"而非"上层"决定的两种方法

结构图卡

内容

界面(interface)的本意是通过对系统确定性加以规格化,来避免持续开发行为对既有部分造成影响。一个确切有效的界面应同时满足四个条件:准确(合适的知识与表达,至少能让交流双方通过某种形式沟通)、有用(明白的意图,至少与系统架构的意图不违背)、可见(执行效果显而易见,至少数据与逻辑流向明确)、可能(应当存在实现手段,至少可以立即着手尝试)。在[[层次结构只允许向下依赖及消解向上依赖的方法|层次结构只允许向下依赖]]这一前提下,界面必然由下层来规格化,而非由上层决定——这里有一个看似合理却行不通的直觉:”上层所需”决定规格更贴合使用场景,但上层在时序上总是相对未确定的,依据尚未确定的东西去定规格,注定缘木求鱼;然而仅凭”下层具有”来定规格,虽然逻辑上讲得通,却常因考虑不周而限制上层的实际使用。书中给出两种改善方法:第一种是不过早追求底层界面的精确与完备,先把下层功能粗略地发布为一个初版接口,让上层基于它做设计细化,再把细化后的设计下沉回底层发布为公共接口的新版本——本质是”上层细化接口、下层负责发布”;第二种方法回到向下依赖只有两类的事实(上层对下层的数据依赖、嵌套结构里向下的注册逻辑),据此得出一般层次系统只需要数据界面、框架/引擎类系统只需多维护一个注册逻辑,这正是REST和CRUD能应付大多数场景的原因,但这种做法会让系统整体趋于扁平、承载规模和复杂性的能力不足,往往只是权宜之计,过一段时间仍要从上层抽取出确定的逻辑重新形成新的层次。可迁移启发:设计一个内部API时,与其争论”接口该照顾上层需求还是照顾下层实现”,不如直接采用”下层先发布一个粗糙但完整的初版,让上层的实际使用倒逼出精细化版本,再把这个精细版本下沉发布”这套渐进流程,它比一开始就试图设计完美接口更贴近现实。

结构图

flowchart TB
  I["界面的四个有效条件"]
  I --> I1["准确:合适的知识与表达可沟通"]
  I --> I2["有用:意图与架构意图不违背"]
  I --> I3["可见:数据与逻辑流向明确"]
  I --> I4["可能:存在可立即着手的实现手段"]
  Q["规格由谁决定?"]
  Q --> A["方法一:上层细化接口<br/>细化后下沉,由下层发布新版本"]
  Q --> B["方法二:下层只维护数据界面+注册逻辑<br/>(REST/CRUD够用,但系统趋于扁平)"]

参考来源

- 位置:《我的架构思想:基本模型、理论与原则》第6章《架构的表达与逻辑》之"6.6 系统确定性是界面原则的核心"(源文件:_epub-src/ch016.xhtml) - 结论依据:原文说明界面"应当完全满足如下条件:准确……有用……可见……可能……界面必是由下层来规格化的……上层的开发活动可以基于这些功能与数据进行设计细化……然后,我们只需要将Intf_Ln v1下沉到L0层,并以之为公共接口Intf_L0 v1发布即可……一般层次系统只需要数据界面,而框架/引擎类的层次系统只需要多维护一个注册逻辑即可", 直接支撑本卡关于界面四条件与两种规格确定方法的结论。 - 原始内容:上层总是(在时序上、相对的)还未能确定的,因此依据"上层所需"来决定规格细节显然是缘木求鱼的事情。