仓库源文

.. Kenneth Lee 版权所有 2018-2020

:Authors: Kenneth Lee :Version: 1.0

让设计自生


上周在单位做了一个架构设计方面的演讲,期间提出一个观点:所有的流程,架构,设计 ,如果不是自生的,必然是多余的。不少听众对这个话题很有兴趣,我在这里稍微Deep Dive一下。

还和那个演讲一样,我需要稍微讲一点点哲学概念,然后才能说明白这个问题。我这里要 谈的这个哲学概念叫“坐进此道”,如果你不能对“坐进此道”有所认识,我们谈什么都是谈“ 名”,谈名就是耍嘴皮子,我没有什么兴趣。

什么叫坐进此道?就是——你用行动和事实来沟通,而不是用名字来沟通。举个例子,你说 ,“去吃饭吧”,然后你穿衣服,拿钱包,锁门,直奔饭馆……这叫坐进此道。穿衣服,拿钱 包,锁门……这些行为,都是“去吃饭”这个名背后的事实支撑。但如果你躺在沙发上,拿着 手机,正在全神贯注吃鸡,一边口里嚷着:“去吃饭,去吃饭,赶紧的。我是最支持吃饭的 了,没有人比我更知道吃饭的重要性。人是铁,饭是钢,一顿不吃饿得慌……”,这就是单纯 的“名”了。

只要能说出来的,看到的,都是名,你穿衣服,拿钱包,锁门,直奔饭馆……然后在饭馆门 口继续吃鸡,这也不叫“去吃饭”。所以,这个只能你我心照,你不肯心照(或者不能心照 ),那谈什么都没有意义。

名和现实的距离(特别是时间距离)越远就越难判断两者是否具有对应关系,所以我们虚 心实腹。肚子饿了,吃饭能解决,这个距离比较近,我们可以相信。提高工程师待遇就能 让产品成功?不搞房地产中国就能搞出芯片?这种就难说了。所以,我们可以先讨论点眼 前的(实腹),心那个部分,需要特别的考量技巧,和足够多的共识,我们可以虚一些。 大部分时候,我们如果肯看现实,而不是为了“争赢”,共识还是有的。

所以,我谈道德经的时候,基本都是结合着技术趋势,编程,构架设计来谈,也是上面说 的这个意思。你说你说:“道德经过千年的流传,世界上有70%的科学家都给出了好评,85% 富翁都读过,我每天读三遍,果然中了六合彩……”,或者你说,“老子易经论语黄帝内经等 等这些书籍有个共同的特点,就是模糊不清。但总体的目标指向却很明确,就是为专制为 稳定找方法,这种方法就是所谓的道……”。他么的这有一个字和道德经有关系吗?把“道德 经”换成“量子物理”,这没有任何区别。这就没有“坐进此道”。因为谈的是个名字,不是那 个事情本身。我对这类行为的评价就是“在名上打转”或者“一直在天上飘”。我不和一直在 名上打转的人讨论问题的,因为名可以无限扩展,没有尽头的,讨论这种东西就是浪费时 间。

好了,如果你理解了这个概念,我们就可以进入“自生”这个观点了。一般底层设计会很快 变现为代码,代码会很快变现为程序(功能),所以,底层设计不太容易在天上飘,因为 飘不了两下,就栽下来了。但架构设计本身就是一种长远策略,这种名,非常容易在天上 飘。我用什么办法才能保证它不在天上飘呢?那我就要用“收益”隔空“撑”住它。

比如“封装”,就是一个飘在空中的概念,一个函数可以封装,一个文件可以封装,一个对 象可以封装,一段连续的代码也可以封装,几个封装也可以封装。“封装”听起来好,但封 装不产生收益,它不会让执行速度变快,代码量变少,功能得到满足。所以,我们要让一 个工程的代码量增加起来,驱动力一定不能是“封装”,而是效率,代码量(意味着维护工 作量),功能……这些利益。

我们为什么要封装?最终我们的目的必然是降低代码量,比如A,B对象中有重复的代码, 把A,B公共的逻辑提出来,变成C,这个系统的代码量就可以降低一个K(K=C-C的接口成本 ),把C的接口收窄(变成高内聚,低耦合),也是一种降成本。但你需要注意到,如果C 的接口成本大于C,K是可以是负值的。

所以,封装需要用降低代码量来背书,封装本身不能作为目的。不少刚学C++的工程师,啥 访问都要写个get/put接口,好像很高大上,结果一半的代码量被用在这种根本用不上的地 方,自以为自己“构架很好”,其实都是浪费时间。

往深一点说,所有的封装都可以用“未来可能”来解释,但这样还是会没有利益支点。所以 ,如果你的解释是“未来可能”,你要用“这种可能是如何发生”的来背书。如果你给不出, 或者你给出的距离很远,我们就得让它“虚”着。

所以,好的架构师无名,因为他是把别人的代码逼退回去,让别人的代码变成“分层”,“封 装”。坏的架构师写一堆的Pattern,封装,分层……结果就是在让名称空间更加的复杂,代 码量更大,性能更低。

读者可以分出这里的区别吗?前者是工作在“全部代码”上面的,这是“坐进此道”,后者是 工作在“自己的代码”上面的,这是“在名上打转”,求礼。

架构师的工作是为全部的代码“坐进此道”,让代码本身符合架构,而不是自己去“做”架构 ,让程序有“架构的样子”。让设计自生,是让它靠“现实约束”成型,而不是靠“定义”成型 。程序是这样长成的:

这个循环让程序可以一直运行-->这个添加让程序可以从socket上收发消息-->这个添加可 以让程序可以和客户端共享会话id-->……->这个添加让客户端和程序共享解码代码……

而不是:

建立一个工厂模式-->这个添加建立socket这个对象,封装30个接口-->这个添加建立解码 库,支持6种变体三种算法-->....

这样建出来的,必然是个玩具,因为只有玩具才可以这样没事找事的。