编程杂谈:从人类与软件系统的根本矛盾说起

Java基础

浏览数:442

2019-9-8

在纷繁复杂的概念满天飞舞的软件编程领域,希望能分享自己整理的一些观点,帮助大家穿透迷雾,看清问题以及解决方案的本质。

人类认知能力上限

有一个说法:人的短时记忆广度平均数为7,即大多数人一次最多只能记忆7个独立的块(Magic number 7)。

有另外一个说法:当需要根据短时记忆进行信息加工时,一个成年人能处理的块的个数是4左右(Working memory)。

这些说法不一定完全正确,但我们可以肯定的是,人类处理信息、加工信息的能力是有上限的。

软件系统的复杂性

然而要完成一个有实际意义的软件业务系统,绝对不是处理4个变量或者7个变量就能完成的,完整的业务其所需处理的数据要大几个量级。

由此软件系统的复杂性与人类认知能力存在上限形成了一个矛盾。当复杂度超过人类可控制的范围时,我们就可以认为其失控了。

我们要怎么避免软件系统失控?或者说如何正确可控地完成一个软件系统呢?大家可以先思考10秒。

既然矛盾是两个方面的事情,那解决矛盾也可以从两个方面入手:

  • 一个是分而治之,将问题分解成人类可控的范围大小

  • 一个是从软件复杂度方面出发,控制总体复杂度

分而治之

要进行分治的话,有也两个问题要解决

  • 按什么逻辑分组

  • 每个问题的规模大小

对于第一个问题的答案就是我们经常听到的

高内聚,低耦合

上述指导原则,能让紧密耦合的逻辑、数据归集到一起,能更少牵制(接口、协议)地进行内部演进。

而存在的 接口、协议 能让我们可以以更高维度的抽象来组织我们的逻辑。

就像我们组装电脑时,只要主板与CPU、硬盘、显卡等等的接口协议确定了,那么主板就可以不管各类组件的具体品牌,型号地组织不同部件的工作,而各个组件都可以在接口的控制下各自独立改进。

对于第二个问题,则是:

子问题规模应为单个人认知极限规模的70%左右

如上图,问题可以分解成不同的层级。上图把问题及解决方案分解成了3层,核心问题、子问题、孙问题。

之所以有层级的存在,是因为子问题的解若数量太多的话,一个人也是无法整合处理的,因此要处理的子问题解数量必须在一个人的可控范围内。但数量控制了,子问题的规模可能很大,并非一个人能求得,因此需要继续划分孙问题。

从上一段的文字我们也可以得出一个结论,子问题并非越小越好,而是尽可能的大,如此才能减少问题的层级,也减少了整合子问题而产生的消耗(也就是说微服务不是越小越好),而问题规模为个人处理极限的70%则是为了应对后续变化,需要预留一定的buffer。

总体复杂度控制

总体复杂度存在一个极限最小值,其由问题域的本质复杂度决定。

然而我们的解决方案会在本质复杂度的基础上,有意无意地引入其他很多额外的复杂度:

  • 由于人类认知极限而进行子问题分解、整合而产生的复杂度

  • 由于未透彻理解问题本质而引入的额外复杂度,如错误的设计而形成畸形的、绕了远路的解决方案

  • 由于错误判断问题的演化方向而引入了额外的复杂度,这个可以理解为过度设计

  • 由于一些问题域外的其他需求引入的额外复杂度,如为了监控、排查问题等等而引入的复杂度

  • 由于代码腐化导致的复杂度,如复制代码块,补丁式代码等等

  • 由于性能问题引入的复杂度

  • ……

可以说,引入复杂度的原因有千万种。而我们能做的,只有一件事情——每次引入复杂度时都认真思考其是否必要,是否利大于弊。

然而我们不能指望于每个人都有能力以及觉悟去审视这个问题,因此自上而下的设计以及监督是必须的,否则代码的整体复杂度就会不断提升,与热力学第二定律有点类似

孤立系统的熵(混乱程度)永不自动减少,熵在可逆过程中不变,在不可逆过程中增加。

一个良好设计的系统,在后续没有经过上层设计以及监督(外部系统做功)的软件系统的混乱程度会不断增加,直到系统的混乱程度变得与编码的程序员思维混乱程度一致(当然或许编码程序员的思维并不混乱,对代码也有自己的要求,这样系统或许会不再腐化,甚至进化,但我们没办法做到每个程序员都有这样的水平)。

小结

本文的内容只是写好代码的序章,但由于规模引起的问题最终解决方向都会落到上面提到的 分而治之 以及 总体复杂度控制 上,这个是根源。

分而治之及总量控制不仅仅能在软件领域上应用,我们可以从 公司人事组织架构、天体系统研究等等方面都可以看到应用。

后续文章我会尝试在上面两个方向上继续细化,将 封装、抽象、多态、分层、DDD 等等思想 以及 面向对象语言、微服务、中台等等外功 关联起来。

若本文能给你带来帮助,请点击右下角在看,若本文存在谬误,请帮忙批评斧正,谢谢!

作者简介

多年金融行业经验,现为某Top2互联网银行高级搬砖工,曾在两家TOP3股份制商业银行及一家互金创业公司工作(架构、核心业务主程),EasyTransaction作者,欢迎关注个人公众号,在这里我会分享日常工作、生活中对于架构、编码和业务的思考

 

作者:YOYO&#