# 历史背景

通过回顾架构产生的历史背景和原因，我们可以基本推导出答案：架构设计的主要目的是为了解决软件系统复杂度带来的问题。整个软件技术发展的历史，其实就是一部与“复杂度”斗争的历史，架构的出现也不例外。简而言之，架构也是为了应对软件系统复杂度而提出的一个解决方案。

1. 通过熟悉和理解需求，识别系统复杂性所在的地方，然后针对这些复杂点进行架构设计
2. 架构设计并不是要面面俱到，不需要每个架构都具备高性能、高可用、高扩展等特点，而是要识别出复杂点然后有针对性地解决问题
3. 理解每个架构方案背后所要解决的复杂点，然后才能对比自己的业务复杂点，参考相似方案

<table><thead><tr><th width="146.33333333333331">年份</th><th width="145">事件</th><th>说明</th></tr></thead><tbody><tr><td>1940 年之前</td><td>机器语言</td><td>直接使用二进制码 0 和 1 来表示机器可以识别的指令和数据</td></tr><tr><td>1940 年</td><td>汇编语言</td><td>又叫符号语言<br>1. 用助记符代替机器指令的操作码<br>2. 用地址符号（Symbol）或标号（Label）代替指令或操作数的地址<br>本质上还是面向机器的，因为需要了解CPU 指令、寄存器、段地址等计算机底层的知识。此外，不同 CPU 的汇编指令和结构也不同。</td></tr><tr><td>1950 年</td><td>高级语言</td><td>不需要关注机器底层的低级结构和逻辑，只要关注具体的问题和业务。<br>高级语言可以通过编译程序被编译为适合不同 CPU 指令的机器语言。</td></tr><tr><td></td><td>Fortran<br>LISP<br>Cobol</td><td>FORmula TRANslator，公式翻译器<br>LISt Processor，枚举处理器<br>Common Business Oriented Language，通用商业导向语言</td></tr><tr><td>1960~1970 年</td><td>第一次软件危机</td><td>其根源在于软件的“逻辑”（规模和复杂度）变得非常复杂<br>典型的表现有：软件质量低下、项目无法如期完成、项目严重超支等</td></tr><tr><td></td><td>软件工程</td><td>《人月神话》<br>同样无法根除软件危机，只能在一定程度上缓解软件危机</td></tr><tr><td></td><td>结构化程序设计</td><td>《GOTO 有害论》，第一个结构化的程序语言 Pascal<br>主要特点：抛弃 goto 语句，采取“自顶向下, 逐步细化, 模块化”的指导思想</td></tr><tr><td></td><td></td><td>结构化程序设计本质上还是一种面向过程的设计思想，但通过“自顶向下, 逐步细化, 模块化”的方法，将软件的复杂度控制在一定范围内，从而从整体上降低了软件开发的复杂度，因此成了 20 世纪 70 年代软件开发的潮流</td></tr><tr><td>1980 年</td><td>第二次软件危机</td><td>根本原因是软件生产力远远跟不上硬件和业务的发展<br>主要体现在软件的“扩展”变得非常复杂</td></tr><tr><td></td><td></td><td>结构化程序设计虽然能够解决（也许用“缓解”更合适）软件逻辑的复杂性，但是对于业务变化带来的软件扩展却无能为力，软件领域迫切希望找到新的银弹来解决软件危机，在这种背景下，面向对象的思想开始流行起来。</td></tr><tr><td></td><td>面向对象</td><td>早在 1967 年的 Simula 语言中就开始提出来了，但第二次软件危机促进了面向对象的发展。面向对象真正开始流行是在 20 世纪 80 年代，主要得益于 C++ 的功劳，后来的 Java、C# 把面向对象推向了新的高峰。到现在为止，面向对象已经成为了主流的开发思想。</td></tr><tr><td>1990 年</td><td>软件架构</td><td>虽然早在 20 世纪 60 年代，戴克斯特拉就已经涉及软件架构的概念了，但软件架构真正流行却是从 20 世纪 90 年代开始的</td></tr><tr><td></td><td></td><td>与之前的各种新方法或者新理念不同的是，“软件架构”出现的背景并不是整个行业都面临类似相同的问题，也不是为了解决新的软件危机而产生的，而是先在 Rational 或者 Microsoft 这样的大公司开始逐步流行起来的</td></tr><tr><td></td><td></td><td>1994 年《An Introduction to Software Architecture》<br>“随着软件系统规模的增加，计算相关的算法和数据结构不再构成主要的设计问题；当系统由许多部分组成时，整个系统的组织，也就是所说的“软件架构”，导致了一系列新的设计问题”</td></tr><tr><td></td><td></td><td>因为只有大公司开发的软件系统才具备较大规模，而只有规模较大的软件系统才会面临软件架构相关的问题。<br>1. 系统规模庞大，内部耦合严重，开发效率低<br>2. 系统耦合严重，牵一发动全身，后续修改和扩展困难<br>3. 系统逻辑复杂，容易出问题，出问题后很难排查和修复</td></tr></tbody></table>

软件架构的出现有其历史必然性：

1. 20 世纪 60 年代第一次软件危机引出了“结构化编程”，创造了“模块”概念
2. 20 世纪 80 年代第二次软件危机引出了“面向对象编程”，创造了“对象”概念
3. 到了 20 世纪 90 年代“软件架构”开始流行，创造了“组件”概念

模块、对象、组件本质上都是对达到一定规模的软件进行拆分，差别只是在于随着软件的复杂度不断增加，拆分的粒度越来越粗，拆分的层次越来越高。

> 思考题：为何结构化编程、面向对象编程、软件工程、架构设计最后都没有成为软件领域的银弹？

在古代的狼人传说中，只有用银质子弹（银弹）才能制服这些异常凶残的怪兽。在软件开发活动中，“银弹”特指人们渴望找到用于制服软件项目这头难缠的“怪兽”的“万能钥匙”。

#### 变化之路

软件开发过程包括了分析、设计、实现、测试、验证、部署、运维等多个环节。从 IT 技术的发展历程来看，先辈们在上述不同的环节中提出过很多在当时看来很先进的方法与理念。但是，这些方法、理念在摩尔定律、业务创新、技术发展面前都被一一验证了以下观点：我们可以通过诸多方式去接近“银弹”，但很遗憾，软件活动中没有“银弹”。

布鲁克斯发表《人月神话》三十年后，又写了《设计原本》。他认为一个成功的软件项目的最重要因素就是设计，架构师、设计师需要在业务需求和 IT 技术中寻找到一个平衡点。个人觉得，对这个平衡点的把握，就是架构设计中的取舍问题。而这种决策大部分是靠技术，但是一定程度上也依赖于架构师的“艺术”，技术可以依靠新工具、方法论、管理模式去提升，但是“艺术”无法量化 ，是一种权衡。

软件设计过程中，模块、对象、组件本质上是对一定规模软件在不同粒度和层次上的“拆分”方法论，软件架构是一种对软件的“组织”方法论。一分一合，其目的是为了软件研发过程中的成本、进度、质量得到有效控制。但是，一个成功的软件设计是要适应并满足业务需求，同时不断“演化”的。设计需要根据业务的变化、技术的发展不断进行“演进”，这就决定了这是一个动态活动，出现新问题，解决新问题，没有所谓的“一招鲜”。

以上只是针对设计领域的银弹讨论，放眼到软件全生命周期，银弹问题会更加突出。

小到一个软件开发团队，大到一个行业，没有银弹，但是“行业最佳实践”可以作为指路明灯，这个可以有。

#### 业务目标

软件开发最本质的挑战有两个：复杂和变更。而软件的价值是保证业务的响应力，而与之相对的是开发资源的有限，而各种的软件开发方法论，也都是在研究有限的资源下，如何应对着两个挑战，寻找平衡点，实现业务目标，因为是在寻找平衡点，就说明是有取舍的，所以就没有所谓的银弹的存在。

#### 参考来源

[https://time.geekbang.org/column/article/6463](https://time.geekbang.org/column/article/6463)
