软件复杂性的因素与解决思路
保留所有版权,请引用而不是转载本文(原文地址 https://yeecode.top/blog/19/ )。
软件是复杂的,这一点是软件从业者的共识。也正因为软件的复杂,使得Bug几乎成了和软件绑定的词语。在本文,我们将探讨软件复杂度的原因,及其降低软件复杂度的办法。
我们认为造成软件复杂度的原因有三点:
- 软件的规模:软件的规模往往是庞大的,而且会随着时间的推移不断扩增。
- 软件的结构:软件是在用技术将业务落地,因此在软件内部存在着技术逻辑和业务逻辑这两类逻辑。这两类信息的交织使得任何只懂得一方逻辑的人无法读懂软件的代码。
- 软件的变化:相比于传统系统,软件的需求是在不断变化的。没有人会要求在已经建好的摩天大楼下再挖一个地下室,但在软件行业,这种需求屡见不鲜。
而且以上三点是共存和互相影响的。例如,随着软件规模的扩充,则它会集成更多的功能,也便会接收到更多的变化;软件的变化可能会破坏原有的结构,使得结构进一步混乱;结构的混乱使得软件变得无序,这又增加了软件的代码规模……
要想降低软件的复杂度,可以从以上三个方面分别入手。
规模
控制软件的规模可以有效地降低软件的复杂度。要注意,这里的规模是指功能角度的规模,不是性能角度的规模。
当软件的规模增大时,可以考虑将这些功能拆分开来,拆成不同的子应用。然后让这些应用互相协作,完成原有的功能。这实际上是复杂度的转移策略:将一个应用的复杂度转移到了多个应用和应用的协作中。在这个转移的过程中,复杂度的总量是提升的,但是可以保证拆分出的每个复杂度都在可控的范围内。
往往,每一个应用的规模要控制在6-7个人能够掌控的范围内。因为这个人数时,交流成本相对较低。
应用间的协作实现则可以有专门的团队搭建基础平台完成。这个工作的复杂度也是可控的。
结构
合理的结构规划可以降低软件的复杂度。应该保证软件结构的清晰。
清晰的结构是说软件模块(或者说层次)分明,模块(或者说层次)之间的关系分明。而这些模块之间,最重要的是业务逻辑和技术逻辑之间的分明,确保两者不会交织杂糅,互相干扰。
关于这一块的实现思想,我会单独理清思路介绍。
变化
在软件的设计流程中,能否拥抱变化时一个重要的评价指标。也正因为如此,敏捷取代了传统的瀑布式编程,流行了起来。
敏捷的“最小可用”思路与瀑布的“规划设计”思路不同,大大地压缩了规划设计阶段的时间,而是用频繁的迭代去补足规划设计的缺失。但是,规划的缺失可能造成工作量的成倍增加。或者,我们可以换一种描述:在敏捷开发中,当我们接到需求后,到底是要仔细地规划为以后的扩展留有余地,还是按照敏捷的原则给出最小实现?
我们知道,前期规划设计的丧失,可能需要后期通过大量的返工才能补足。因此,上述问题是敏捷开发中必然面对的一个问题:选择仔细规划就背离了敏捷的初衷,选择最小实现就堵死了扩展的余地。
关于此,有一个解决思路是:只被第一次变化侵扰。
当面临一组需求时,直接按照敏捷的原则给出最小实现。然后,如果哪个需求发生了变更,则我们认为它可能还会变更,于是对哪个需求的实现进行详细的规划,为其保留扩展性。这样,在敏捷和扩展中寻求平衡,以此来拥抱变化。
结语
本文分析了造成软件复杂性的三个因素,并给出了各个因素的解决思路。当然,我们这里仅作思路的探讨,对于每一种思路的具体实现将会涉及到许多具体的细节问题,我们以后再逐渐展开。
可以访问个人知乎阅读更多文章:易哥(https://www.zhihu.com/people/yeecode),欢迎关注。