Complexity is anything that makes software hard to understand or to modify 译:所谓复杂性,就是任何使得软件难于理解和修改的因素。
John Ousterhout 《A Philosophy of Software Design》
50年后的今天,John Ousterhout教授在 A Philosophy of Software Design 书中提到了一个非常主观的见解,复杂性就是任何使得软件难于理解和修改的因素。
模糊性与依赖性是引起复杂性的2个主要因素,模糊性产生了最直接的复杂度,让我们很难读懂代码真正想表达的含义,无法读懂这些代码,也就意味着我们更难去改变它。而依赖性又导致了复杂性不断传递,不断外溢的复杂性最终导致系统的无限腐化,一旦代码变成意大利面条,几乎不可能修复,成本将成指数倍增长。 复杂性的表现形式
复杂的系统往往也有一些非常明显的特征,John教授将它抽象为变更放大(Change amplification)、认知负荷(Cognitive load)与未知的未知(Unknown unknowns)这3类。当我们的系统出现这3个特征,说明我们的系统已经开始逐渐变得复杂了。 症状1-变更放大
Change amplification: a seemingly simple change requires code modifications in many different places.
译:看似简单的变更需要在许多不同地方进行代码修改。
John Ousterhout 《A Philosophy of Software Design》
Cognitive load: how much a developer needs to know in order to complete a task. 译:开发人员需要多少知识才能完成一项任务。
John Ousterhout 《A Philosophy of Software Design》
Unknown unknowns: it is not obvious which pieces of code must be modified to complete a task 译:必须修改哪些代码才能完成任务。
John Ousterhout 《A Philosophy of Software Design》
The Complexity of software is an essential property, not an accidental one.
译:软件的复杂性是一个基本特征,而不是偶然如此。
Grady Booch 《Object-Oriented Analysis and Design with Applications》
Grady Booch在 Object-Oriented Analysis and Design with Applications 中提出这样一个观念,他认为软件的复杂性是固有的,包括问题域的复杂性、管理开发过程的困难性、通过软件可能实现的灵活性与刻画离散系统行为的问题,这4个方面来分析了软件的发展一定伴随着复杂,这是软件工程这本科学所必然伴随的一个特性。
Everything, without exception, requires additional energy and order to maintain itself. I knew this in the abstract as the famous second law of thermodynamics, which states that everything is falling apart slowly.
译:世间万物都需要额外的能量和秩序来维持自身,无一例外。这就是著名的热力学第二定律,即所有的事务都在缓慢地分崩离析。
-- Kevin Kelly 《The Inevitable》
Kevin Kelly在 The Inevitable 也有提过类似的观点,他认为世间万物都需要额外的能量和秩序来维持自身,所有的事物都在缓慢地分崩离析。没有外部力量的注入事物就会逐渐崩溃,这是世间万物的规律,而非我们哪里做得不对。 软件架构治理复杂度
为软件系统注入的外力就是我们的软件架构,以及我们未来的每一行代码。软件架构有很多种,从最早的单体架构,到后面的分布式架构、SOA、微服务、FaaS、ServiceMesh等等。所有的软件架构万变不离其宗,都在致力解决软件的复杂性。 架构的本质
编程范式指的是程序的编写模式,软件架构发展到今天只出现过3种编程范式( paradigm ),分别是结构化编程,面向对象编程与函数式编程。
Almost every software development organization has at least one developer who takes tactical programming to the extreme: a tactical tornado.
译:几乎每个软件开发组织都有至少一个将战术编程发挥到极致的开发人员:战术龙卷风。
John Ousterhout 《A Philosophy of Software Design》
John Ousterhout教授在 A Philosophy of Software Design 书中提到了战略设计与战术设计的总成本投入。随着时间的流逝,战略设计可以有效控制软件成本,但战术设计会随着时间的推移线性递增。这与Martin Fowler在 Patterns of Enterprise Application Architecture 这本书中所提的关于数据驱动与领域驱动关于复杂度的治理是同样的含义,要致力于长期的价值投资。 系统的困境与演进
A condition that is often incorrectly labeled software maintenance. To be more precise, it is maintenance when we correct errors; it is evolution when we respond to changing requirements; it is preservation when we continue to use extraordinary means to keep an ancient and decaying piece of software in operation. Unfortunately, reality suggests that an inordinate percent- age of software development resources are spent on software preservation.
译:我们总是说我们需要“维护”这些老系统。而准确的说,在软件发展过程里,只有我们修正错误时,才是维护;在我们应对改变的需求时,这是演进;当我们使用一些极端的手段来保持古老而陈腐的软件继续工作时,这是保护(苟且)。事实证明我们更多的时间是在应对最后一种状况。
Grady Booch 《Object-Oriented Analysis and Design with Applications》
如同Grady Booch在 Object-Oriented Analysis and Design with Applications 中所提到的观点,当我们使用一些极端的手段来保持古老而陈腐的软件继续工作时,这确实是一种苟且。我们小心翼翼、集成测试、灰度发布、及时回滚等等,我们没有在“维护”他们,而是以一种丑陋的方式让这些丑陋的代码继续能够成功苟且下去。当代码变成意大利面条时,将几乎是不可能修复,成本将成指数倍增长,并且似乎我们的系统已经存在这样的代码,并且可能还在持续增加中。
The goal of software architecture is to minimize the human resources required to build and maintain the required system.
译:软件架构的终极目标是,用最小的人力成本来满足构建和维护该系统的需求
Robert C.Martin 《Clean Architecture》
Robert C.Martin在 Clean Architecture 一书中提到了架构终极目标,用最小的人力成本来满足构建和维护该系统的需求。架构始终是我们解决复杂度的一个工具,如果当前系统并不复杂,我们不需要为了所谓的优雅去过分改造与优化它,持续将成本置在一个较低水位,就是软件最好的解决办法。
业务简单的系统不应用DDD架构,弱交互场景也无需进行前后端分离,哪怕是邓总设计师在规划新中国的发展上,也是制定了一套‘中国特色社会主义’制度。不要盲从一些教条的观念,选择适合自己的,控制在可控制范围内,既不过度也不缺失。毕竟没有绝对的优雅,甚至没有绝对的正确。 写在最后
很多人认为做业务开发显得没那么有挑战性,但其实正好相反。最难解决的bug是无法重现的bug,最难处理的问题域是不确定性的问题域。业务往往是最复杂的,面向不确定性设计才是最复杂的设计。软件工程学科最难的事情是抽象,因为它没有标准、没有方法、甚至没有对错。如何在软件固有的复杂性上找到一条既不过度也不缺失的路,是软件工程师的终身课题,或许永远也无法达到,或许我们已经在路上了。
参阅书籍:
《A Philosophy of Software Design》
Object Oriented Analysis and Design with Applications