.. Kenneth Lee 版权所有 2021
:Authors: Kenneth Lee :Version: 1.0 :Date: 2021-12-08 :Status: Draft
设计和科普
这个概念讨论过,但没有独立拉出来讨论,这两天讨论另一个问题的时候又用到了,所以 这里专门梳理一下这个概念。
在评审设计文档的时候,我们常常看到一些设计描述,它们确实对细节进行了总结,但把 它们认为是设计,总觉得哪里不对,本文就总结这种问题是怎么发生的。
我们用一些具像来构造我们的概念。
比如,我们要做一个代码量统计软件,我们设计它怎么做,我们可以抽象这样一些特征:
这些描述是否“总结”了这个软件的特征?确实是的,我把这样的描述称为“科普”,但我不 承认它是设计。因为如果我进一步开始写代码了,它不能成为我的指导。
下面这个描述可以:
这个描述并不精确,但它确实是设计,先不论它是不是最优的,是不是正确的,但它确实 对下一级设计是有用的,控制性的,知道下一级设计是“在高级设计控制范围内的,还是不 在范围内的”。
我们说,架构设计,或者高层设计,都是严格的,就是这个意思。它确实没有指导每个bit, 每条语句应该怎么写,但它确实限定了范围。
所以,这里的“科普”和“设计”的核心区别是什么呢?这有几个特征:
它是一个要求,是对细节设计的要求。比如“用C写这个程序”,而不是陈述“C语言是一 种优美的语言”。只有这样它才能为下一级设计设定范围。
它是一种选择,是在有多个选择的时候选择其中一种,是“我们不用Python来写这个程序, 而是用C”,而不是“我们要在我们可以使用的语言中选择一种语言”。所有本来就会发生的 事情做的选择,不是设计。
它是一个权衡。换言之,它必须构成一个\ :doc:逻辑闭包
\ 。
最后这个最难理解,我们专门讨论它一下。“进行统计的时候必须使用状态机”,这是一个 要求,也是一种选择(可以选择用状态机,也可以不用状态机)。但用不用状态机,是一 个端到端的算法判断吗?用不用状态机,决定了是否正确统计代码行数吗?用不用状态机 ,可以决定这个软件的成败吗?……都不行。这个东西放在这里,细节设计的人根本不会看, 因为没有用,下一级设计的人,要想的的是怎么组织代码输出正确的代码行数,这是他要 解决的问题,用不用状态机这个约束,对他没有限定作用,这个东西就不是设计。
你看,我们分成三个模块,Parser模块只关注单个文件的Parse,和给定数据的更新,这是 一个有指导性的约束,这是设计。而这个设计是有端到端的理由的:main已经建立一个数 据结构了,分析参数也给出来了,parse点一下,你有这些参数,也有要的数据结构,确实 已经足够可以作统计了,如果有多个文件,这些文件的枚举可以放到main模块中。而且一 旦更新数据结构了,剩下事情和parse无关,reporter喜欢用html输出也行,喜欢stdio输 出也行,都和其他要素无关,这个逻辑也通……这样的过程是可以权衡,可以发现问题的, 这是设计,而受其他逻辑控制的选择和要求,它不需要你来指手画脚,这些吊在半空中的 一个“特征”,不能被认为是“设计”。
所以,设计可以有很多维度,比如还是前面这个程序,我们可以独立建模:
多CPU的情况下,怎么加快前述过程?
支持多种被统计语言的情况下,如果展开多个Parser?
如何实现过滤掉部分不想要的文件?
等等
这些,每个都可以是一个独立的逻辑闭包。它们虽然总结的是同一个软件,但它们只关注 了这个软件的其中一个调整,这些都是设计,所以,4+1五大视图,每个都是设计,因为取 不同的维度进行不同的要求,进行选择,和权衡。
但失去了目标,失去了要求,选择和权衡的,就仅仅是特征的呈现,可以用于“理解”,但 不是一种设计。
这里再补充一些和这个“科普”概念有关的案例:
比如,他们有人喜欢在设计的时候这样说:
XX寄存器在xx条件下有效。
但什么叫有效呢?如果没有详细定义这个有效,这句话就是科普,大概可以明白你的意思 。对于一个寄存器来说,读我总是可以读的,无效的话,是读出来的值不可解释,还是会 发生中断?还是会变成一个固定的值?
所以,这个“有效”无法支撑设计决策。如果我们描述的是具体的行为,说,当xx条件成立 的时候,某某对象表现为xx行为,这就是直接的设计。