感谢早早聊赠送的图书和淘宝妙净的亲笔签名。
前言
作者从1964年开始编程,到2016年已经超过50年,写过小型嵌入式系统、大型批处理系统、命令行、图形界面、进程管理、计费、通讯、设计工具、画图工具等。
领悟是:软件架构的规则是相同的。
这么多千差万别的系统,软件架构规则和其他变量完全无关。今天的软件和过去的软件本质上仍然一样,都是有if语句、赋值语句、以及while循环组成。
50年来工具的质量提升了,编程语言稍微进步了一点,但计算机程序的基本构造没有发生什么变化。
软件架构的规则其实就是排列组合代码块儿的规则。
概述
程序员将需求文档转换成可运行的代码并不难,难的是拥有一个好的架构,架构能力是需要经验和时间,并非所有人都愿意在架构上花时间学习。
好的软件架构可以大大节省软件项目构建和维护成本,让每次变更都短小简单,易于实施、避免缺陷,成本更小。
第一章 架构与设计究竟是什么
简短的说明:架构和设计一丁点去区别都没有。
软件架构的终极目标是,用最小的人力成本满足构建和维护系统的需求。
接着作者举了几个例子来说明糟糕的设计是如何给公司代码人力成本的增长。
引用龟兔赛跑的故事:
- 慢但是稳,是成功的秘诀。
- 比赛并不是拼谁开始跑得快、谁更有力气。
- 心态越急,反而跑得越慢。
并提示我们:不要过于自信,不要持续低估那些好的、良好设计的、整洁的代码的重要性。要想跑的快,先要跑的稳当。
并且在结尾提出一个问题:如果挽救一个系统的办法是重新设计一个新的系统,那么,我们有什么理由认为从头开始,结果会更好呢?
第二章 两个价值维度
程序员并不应该把“按照需求文档编写代码,并修复bug”当做工作的全部。
提出的每个新需求好像一个不规则的拼图块,要在现有的拼图中插入这个拼图块,拼出一个新的形状。如果我们的架构设计偏向于维持整体形状,那么每次变更将非常艰难,好的架构设计应该做到与“形状”无关。
但在日常的开发工作中,架构设计工作并不会被放在它匹配的优先级上:
所以,平衡系统架构的重性与功能的紧急程度这件事,是软件研发人员自己的职责。
架构师的职责就是创建一个功能容易、修改简单、扩展轻松的架构,如果忽视架构的长期价值,一个系统变得难以维护,那么说明软件开发团队没有和需求放做足够的抗争,没有完成自己应尽的职责。
第三章 编程范式总览
结构化编程、面向对象编程、函数式编程三个编程范式都是在 1958 年到 1968 年这 10 年间被提出来的,后续再也没有新的编程范式出现过。
- 结构化编程对程序控制权的直接转移进行了限制和规范。
- 面向对象编程对程序控制权的间接转移进行了限制和规范。
- 函数式编程对程序中的赋值进行了限制和规范。
第四章 结构化编程
科学理论和科学定律的特点:它们可以被证伪,但是没有办法被证明。
Bohm 和 Jocopini 证明了人们可以用顺序结构、分支结构、循环结构这三种结构构造出任何程序。
Dijkstra 认为程序员可以像数学家一样对自己的程序进行推理证明,可以用代码将一些己证明可用的结构串联起来,只要自行证明这外代码是正确的,就可以推导出整个程序的正确性。
最早的go to 语句的某些用法会导致某个模无法被递归拆分成更小的、可证明的单元。
结构化编程范式中最有价值的地方就是,它赋予了我们创造可证伪程序单元的能力。 这也是为什么在架构设计领域,功能性降解拆分仍然是最佳实践之一。
这让我明白了为什么说“测试覆盖率100%”和“不存在bug”之间关系的根源:
第五章 面向对象编程
面向对象编程的3个特性:
- 封装可以把一组相关联的数据和函数圈起来,使圈外面的代码只能看见部分函数,数据则完全不可见。
- 继承的主要作用是让我们可以在某个作用域内对外部定义的某一组变量与函数进行覆盖。
- 多态是同一个行为具有多个不同表现形式或形态的能力。
多态解决了依赖反转问题: 如实现一个播放器函数,要求可以播放音频和视频;音频、音频分别依赖自己的流接收、解码、播放函数,在没有多态概念时,要在播放函数中引入音频、视频各自的流接收、解码、播放等函数,换言之,这些底层的实现函数是这个播放器函数的强依赖。
有了面向对象的多态以后,视频、音频变成2个单独的解析器对象,播放器只需要根据不同的类型,区分调用视频的play方法,还是音频的paly方法,具体内部的流接收、解码等函数统统封装在它们内部,独立开发、独立部署。
以C语言为例,都可以实现这3种特性,面向对象编程并没有在封装、继承、多态开创出新或提出新的概念。但是面向对象编程语言提供了更便利、安全的使用这3种特性的能力。
面向对象编程就是以多态为手段来对代码中依赖关系进行控制的能力。让架构师实现高层策略性组件与底层实现性组件相互分离,构建出插件式架构。
第六章 函数式编程
特点:函数式变成中的变量是不可变的。
可变性会导致很多问题,在一个复杂的系统中,如果底层函数能够轻松更改一个重要的公共变量,那将是一场灾难。
一个架构设计良好的应用程序应该将状态修改的部分和不需要修改状态的部分隔离成单独的组件,然后用合适的机制来保护可变量。
软件架构师应该着力于将大部分处理逻辑都归于不可变组件中,可变状态组件的逻辑应该越少越好。
总结
- 结构化编程是对程序控制权的直接转移的限制。
- 面向对象编程是对程序控制权的间接转移的限制。
- 函数式编程是对程序中赋值操作的限制。
这三个编程范式都对程序员提出了新的限制。每个范式都约束了某种编写代码的方式,没有一个编程范式是在增加新能力。
也就是说,我们过去 50年学到的东西主要是一一什么不应该做。
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!