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

第一个典型错误:不抽象。比如你做一个设备,这个设备的软体烧到设备上,软体有很多类型,比如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赢他们,要不修改你的设计。无论如何吧,架构设计一刀子都是又快又狠地切下去的,然后根据反弹的程度(以及不断增长的信息)来进行一步步修正,从而既保证了你的目标得以推行,又保证这个目标推行的时候不会大幅伤害可实施性。

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

推荐阅读:

相关文章