仓库源文

.. Kenneth Lee 版权所有 2019-2020

:Authors: Kenneth Lee :Version: 1.0

:dtag:架构设计案例

一些典型的架构设计错误


这篇文档没有新东西,是最近评审了一个比较大型的架构设计,感觉该犯的典型错误都犯 了,这里记录一下,作为以后举例子时的参考吧。

第一个典型错误:不抽象。比如你做一个设备,这个设备的软件烧到设备上,软件有很多 类型,比如bootloader,kernel,FS镜像,独立可升级软件部件,配置数据,备份数据等 等。你做架构设计,从烧写的角度,你管这是bootloader还是kernel还是FS镜像呢?你关 注是的flash分区这个概念,这些东西应该称为分区数据。这个部分的设计就应该基于分区 数据来谈。你不抽象,在烧写逻辑下认知被烧写的每个不同的对象。然后,在下一个角度 ,比如在源代码管理这个逻辑下,认知每种不同的对象的源代码管理。每个抽象角度你都 用被你描述对象的全集来覆盖。你的逻辑就会变得非常复杂,写架构就变成写代码了。写 架构变成写代码不是勤奋,是“用战术的勤奋掩盖战略的懒惰”。关键是,你让我看你这么 复杂的逻辑链,我根本看不下来,我看不下来,参与你这个项目的其他人其实也看不下来 ,最终的结果是什么呢?——当然就是没有架构了,你写的都是废话——进不了别人心里的, 当然都是废话。

这个错误有一个变体。不抽象,常常就带着没有角度。你说你怎么烧写,和你怎么管理源 代码,是两个独立的角度。你非要把如何烧写,和你选择了github管理你的源代码建立关 联(比如烧写的时候用github来保存一些数据),以后想换别的代码管理平台,就不用换 了。这样设计法,一开始就让本来没有关联的东西变成混沌系统。

第二个典型错误是第一个错误引起的——逻辑不完整。因为没有抽象,逻辑就变得非常复杂 ,比如根文件系统有100个包吧,你不抽象,有些包是tar打的,有些包是rpm,有些包里面 放了一个metadata,有些包放了些描述文件。然后你就一个个说吧,但肯定说不完,然后 就一些有,一些没有。然后你说这个设计能否实施呢?鬼知道,你都已经陷入细节了,高 一层的逻辑已经没有了,这就是没有架构设计。所以,虽然你写了上百页的文档,这些也 不是架构设计。架构设计已经在你这层丢失了。

这种丢失其实常常发生在历史阶段,比如做一个项目,一开始根本就没指望有长远发展, 临时做起来的,这里加加,那里加加,就会变得很复杂。后面赚大钱了,做下一个版本, 轻易也不敢动原来的东西,这时应该怎么办呢?——还是那句话——不为天下先。已经成了这 样了,就让它这样吧(你不是赚大钱了么)。但你不是要设计吗?你决定你要设计什么就 好了,混沌的部分,你要不有资源有收益整理掉,要不你就绕着它走。但你的架构设计应 该明确知道(乃至定义)这个部分是个混沌系统。很多人在架构设计中看不得脏,却在实 施中忍得了脏。这不是架构师应该做的,架构师需要反过来。架构设计时忍得了脏,面对 最黑的一面。实施的时候严格按架构设计来执行,容不下脏。这样才能让目标得以保持。

所以,前面那个例子中,如果你能容忍有这么多包,反正的系统就能跑了,也能加减包了 ,就先这样呗,但假如你要加入动态安装功能,你可以直接定义一种你要求的包的格式, 然后增加直接,保证这种“可动态安装包”的格式符合你的要求,基于这个来推演你的整个 动态安装过程好了。

其实这个错误的本质就是每个逻辑链都太长。你说30行代码,你能看得出有没有破绽。 10000行你怎么看得出,你肯定是需要把它通过函数组织,把每个独立逻辑缩减到30行,才 好分析这个逻辑有没有错的对吧。同样道理,你一个自洽的逻辑,表述在2页的文档中,我 还能看出有没有破绽,你放在100页的文档中,你给谁看呢?你自己都不知道逻辑是不是通 的,对吧。

第三个典型错误:没有错。最没用的架构设计是没有错,不被人反对的架构设计。这几乎 是所有初学者必犯的错误,而且是最严重的错误。比如说,你设定一个原则:“rule1:所 有软件包必须保证和其他软件包解耦”。

这句话肯定没错,问题是,Who care? 这话说了等于没说,这种原则完全不痛不痒,用来 在知乎上写鸡汤还马虎,用来做设计?

又比如说,你去详细定义一个安装的过程,没有人能看出这个设计有没有错。但你设计这 个东西想给谁看?

架构设计不是代码,不是实现。你是去干涉别人的实现,别人必然会干的东西,要你多说 一句吗?

架构设计设定的每个设计要求,都是刀子,是一刀切下去,一堆人会痛,要跟你撕逼的。 这才是架构设计。你所有的设计,听众都是点点头,当做没有说过一样,你这个设计必然 做错了。你不是做详细设计的人,你对于那些模块都是外行,你不可能不错的。比如你要 统一安装包的格式,以便可以统一安装,统一升级。你要求所有的软件包都用rpm格式打包 ,并且交叉安装在Host上,然后压缩成squashfs烧到单板上。做UEFI的人就该来找你麻烦 了(根本没有目标安装目录),从Debian直接引入源代码的人也来找你麻烦了(可能因为 他们遵循的目录树放置规则,或者使用的libc库和你的要求不兼容?),你要不K赢他们, 要不修改你的设计。无论如何吧,架构设计一刀子都是又快又狠地切下去的,然后根据反 弹的程度(以及不断增长的信息)来进行一步步修正,从而既保证了你的目标得以推行, 又保证这个目标推行的时候不会大幅伤害可实施性。

我不知道我说明白这个问题没有,真希望可以让读者看看那些“不狠”的构架设计,基本上 这些貌似什么都没有错的构架设计啊,就和没有设计一样。