软件复杂性的因素与解决思路

标签: 架构设计

保留所有版权,请引用而不是转载本文(原文地址 https://yeecode.top/blog/19/ )。

软件是复杂的,这一点是软件从业者的共识。也正因为软件的复杂,使得Bug几乎成了和软件绑定的词语。在本文,我们将探讨软件复杂度的原因,及其降低软件复杂度的办法。

我们认为造成软件复杂度的原因有三点:

而且以上三点是共存和互相影响的。例如,随着软件规模的扩充,则它会集成更多的功能,也便会接收到更多的变化;软件的变化可能会破坏原有的结构,使得结构进一步混乱;结构的混乱使得软件变得无序,这又增加了软件的代码规模……

图片

要想降低软件的复杂度,可以从以上三个方面分别入手。

规模

控制软件的规模可以有效地降低软件的复杂度。要注意,这里的规模是指功能角度的规模,不是性能角度的规模。

当软件的规模增大时,可以考虑将这些功能拆分开来,拆成不同的子应用。然后让这些应用互相协作,完成原有的功能。这实际上是复杂度的转移策略:将一个应用的复杂度转移到了多个应用和应用的协作中。在这个转移的过程中,复杂度的总量是提升的,但是可以保证拆分出的每个复杂度都在可控的范围内。

往往,每一个应用的规模要控制在6-7个人能够掌控的范围内。因为这个人数时,交流成本相对较低。

应用间的协作实现则可以有专门的团队搭建基础平台完成。这个工作的复杂度也是可控的。

结构

合理的结构规划可以降低软件的复杂度。应该保证软件结构的清晰。

清晰的结构是说软件模块(或者说层次)分明,模块(或者说层次)之间的关系分明。而这些模块之间,最重要的是业务逻辑和技术逻辑之间的分明,确保两者不会交织杂糅,互相干扰。

关于这一块的实现思想,我会单独理清思路介绍。

变化

在软件的设计流程中,能否拥抱变化时一个重要的评价指标。也正因为如此,敏捷取代了传统的瀑布式编程,流行了起来。

敏捷的“最小可用”思路与瀑布的“规划设计”思路不同,大大地压缩了规划设计阶段的时间,而是用频繁的迭代去补足规划设计的缺失。但是,规划的缺失可能造成工作量的成倍增加。或者,我们可以换一种描述:在敏捷开发中,当我们接到需求后,到底是要仔细地规划为以后的扩展留有余地,还是按照敏捷的原则给出最小实现?

我们知道,前期规划设计的丧失,可能需要后期通过大量的返工才能补足。因此,上述问题是敏捷开发中必然面对的一个问题:选择仔细规划就背离了敏捷的初衷,选择最小实现就堵死了扩展的余地。

关于此,有一个解决思路是:只被第一次变化侵扰。

当面临一组需求时,直接按照敏捷的原则给出最小实现。然后,如果哪个需求发生了变更,则我们认为它可能还会变更,于是对哪个需求的实现进行详细的规划,为其保留扩展性。这样,在敏捷和扩展中寻求平衡,以此来拥抱变化。

结语

本文分析了造成软件复杂性的三个因素,并给出了各个因素的解决思路。当然,我们这里仅作思路的探讨,对于每一种思路的具体实现将会涉及到许多具体的细节问题,我们以后再逐渐展开。

本文首发于个人知乎:易哥(https://www.zhihu.com/people/yeecode),欢迎关注。

作者书籍推荐