简约之美:软件设计之道

作者:Max Kanant-Alexander (开 源 项 目 Bugzilla 总 架 构 师)
译者: 余晟
读者:锅巴GG

编程是把复杂问题化解为简单问题的劳动。一旦程序达到某种复杂程度,就没有人可以理解了。
程序中复杂的部分必须以某种简单方式组织起来,这样,不需要神那样强大的思维,普通程序员也可以开发出来。
这就是编程所要用到的艺术和才能——化繁为简。

“好程序员”应当竭尽全力,把程序写得让其他程序员容易理解。因为他写的东西都很好懂,所以要找出 bug 是相当容易的。
这个关于简单性的想法有时被误解为:程序不应当包含太多代码,或者是不应当使用先进技术。这么想是不对的。有时候,大量的代码也可以带来简单,只不过增加了阅读和编写的工作量而已,这是完全正常的。你只要保证,那些大段的代码提供了化解复杂性所必须的简短注释,就足够了。同样,通常来说,更先进的技术只会让事情更简单,只是一开始你得学习,所以整个过程可能没那么简单。

写程序时,在我们和计算机之间没有任何人。我们让计算机干什么,就会得到怎样的结果;计算机绝对服从命令。结果的质量完全取决于机器的质量、我们想法的质量,代码的质量
在这三个因素当中,代码的质量是如今软件工程需要面对的最重要问题。所以全书主要在论述如何提高代码质量。

我们学习提高代码质量的全部原因都在于,要想改进结果,提高代码质量是最重要的问题。
所以,我们最需要掌握的,就是提高代码质量的科学方法。

  • 软件设计的科学就是为软件做计划、制定决策的科学,它帮助大家做出这类决定:
  1. 程序的代码应当采用什么结构?
  2. 是程序的速度重要,还是代码容易阅读重要?
  3. 为满足需求,应该选择哪种编程语言?
  • 软件设计与下列问题无关:
    1. 公司的结构应该是怎样的?
    2. 什么时候召开团队会议?
    3. 程序员的工作时间应该如何安排?
    4. 程序员的绩效如何考核?

软件系统中任何与架构有关的技术决策,以及在开发系统中所做的技术决策,都可以归到“软件设计”的范畴里。

软件设计的基础规则是什么?

书中列出了关于软件开发的若干定义、事实、规则、定律,它们的着眼点大多在于软件设计。可是,定义(Definition)、事实 ( Fact )、 条例 ( rule )、 规则 (Law) 的差别在哪里呢?

  1. 定义告诉你事物是什么,应当如何使用。
  2. 事实是关于事物的真实陈述。每一点真实的信息都是事实。
  3. 条例是给你的确切建议,它包含某些具体的信息,用于制订决策。
    但是,条例并不能帮你绝对准确地预测未来,也不能帮你发现其他
    真理。它们通常会告诉你是否需要采取某些行动。
  4. 规则是永远为真的事实,它涵盖了很多领域的知识。它们帮你发现
    其他重要的真理,帮你预测未来要发生的事情。

软件设计是有章(规则)可循的,它们可以被认识,可以被理解。规则是永恒不变的,是基本的事实,而且确实可行。

《人月神话》之后涌现出了大量的软件开发方法:Rational 统一过程、能力成熟度模型、敏捷软件开发,等等。它们无一标榜自己是科学——虽然它们只是管理软件开发复杂性的手段。
正是这一切,导致了现状:方法众多,真正的科学却缺席。
其实,缺席的科学分为两种:软件管理的科学,软件设计的科学。
软件管理的科学告诉我们的是,如何为程序员分派工作,如何制订发布计划,如何估量任务所需的时间,诸如此类。这是一门显学,上述的各种方法强调的正是这一点。在这个领域中,存在着彼此矛盾却各有道理的观点,这说明软件管理的基本规律尚未被认识。不过,大家已经关注到了这个问题。但是,软件设计的科学在现实的编程中却没有什么人关注。

全书提供的是“实际干活的程序员”所需科学的入门部分——在任何语言中编写程序时都应当遵循的若干基础定律和规则。这种科学与物理和化学一样可靠,它告诉你如何编写程序。

  • 其实,全部软件都有一个相同的目标: 帮助其他人

软件设计科学的目标

  • 确保软件能提供尽可能多的帮助。
  • 确保软件能持续提供尽可能多的帮助。
  • 设计程序员能尽可能简单地开发和维护的软件系统,这样的系统才能为用户提供尽可能多的帮助,而且能持续提供尽可能多的帮助。

软件设计师面对的主要问题是:“在设计软件时,应该做怎样的决定?”面对的众多可能,哪一个才是最好的。我们不是要确定绝对的好坏,而是要知道:“这些可能的选择中,哪些更好?”这是个排序问题,我们要做的是从所有可能中选出最好的决定。

软件设计的方程式

任何一点改变,其合意程度与其价值成正比,与所付出的成本成反比。

软件设计方程式

D 表示这个变化的合意程度(可取程度)。我们对此项工作的需求有多么迫切?
V 表示它的价值。该变化价值几何?一般来说,你可以问自己“这个变化对用户有多少用”;当然,还有很多其他方法来判断其价值。
E 表示完成这个变化的成本,也就是完成它需要付出的代价。

这并不是在判断某个变化绝对对错,而是指导你如何分辨并排序你的选项。能带来较大价值、花费成本较少的变化,要比带来较少价值、花费较多成本的变化“更好”。

设计的质量

设计的质量好坏,正比于该系统在未来能持续帮助他人时间的长度。

不可预测的结果

设计软件时最应该关注的是未来。不过,关于任何工程,都有一点极为重要:

未来的某些事情,是我们所不知道的。

其实,软件设计也是如此,关于未来,大多数事情都是未知的。

程序员犯的最常见也是最严重的错误,就是在其实不知道未来的时候去预测未来。

变化

随着时间的流逝,软件所处的环境会变化。没有东西可以永恒不变。也就是说,软件必须随环境变化而变化,才能适应所处的环境。
于是,我们得到了变化定律(Law of Change):

程序存在的时间越久,它的某个部分需要变化的可能性就越高。

  • 软件设计的三大误区

按照其发生频率逐一列出来:
(1) 编写不必要的代码——“你不会需要它”(YouAin’t Gonna Need It)
(2) 代码难以修改——“僵化设计”(rigid design)
(3) 过分追求通用——“过度工程”(overengineering)

  • 如何避免?

渐进式开发及设计

“缺陷概率定律”

在程序中新增缺陷的可能性与代码修改量成正比。

  • 理想的设计是怎样的:
    最好的设计,就是能适应外界尽可能多的变化,而软件自身的变化要尽可能少。
    这个说法,简练融合了如今关于优秀的软件设计的各项知识。
  • 如果这不是问题——获得证据是很重要的
    永远不要“修正”任何东西,除非它真的有问题,而且有证据表明问题确实存在。
  • 避免重复
    理想情况下,任何系统里的任何信息,都应当只存在一次。

简洁定律(Law of Simplicity)

软件任何一部分的维护难度,反比于该部分的简洁程度。
某一部分的代码越简洁,未来进行变化的难度就越低。完全消除维护的难度是不可能的,但这正是我们要争取实现的目标:如果要进行彻底的变化,或者新增大量代码,不应该遇到多少困难。

  • 简洁与软件设计方程式

简洁定律告诉我们:目前可行的、能够降低软件设计方程式中维护成本的最重要的事情,就是把代码变简洁。我们不必预测未来,完全可以只审视自己的代码,如果它足够复杂,就立刻动手简化它。这就是随时间推移降低维护成本的办法——持续不断地让代码变得更简洁。

  • 简洁是相对的

如何定义“简洁”,却取决于你的目标受众。
文档和注释,应用场合(上下文)也是非常重要的。

  • 简洁到什么程度?
    面对“要做到多简洁”这种问题时,你可能需要同时问自己:“我究竟是要让用户理解,感到快乐,还是让他们困惑,感到沮丧?”如果选择前者,确保成功的复杂度就只能是:简单到傻子都能懂。

  • 保持一致

如果你在一个地方采用了某种规则,就应当在其他每个地方都遵守这种规则。

  • 可读性

软件开发领域反复强调一点:代码被阅读的次数远多于编写和修改的
次数。所以,保证代码容易阅读很重要。
代码可读性主要取决于字母和符号之间的空白排布。

  • 简洁离不开设计

没有人天生就会构建简洁的系统。如果设计师不倾注精力,系
统就会逐渐变成杂乱庞大的怪物。

复杂性

软件开发中开发速度越来越快不起来,问题的根源都在复杂性。开始的时候项目是简单的,只要一个月就能完成;然后复杂性增加了,于是需要三个月时间;再然后,每个部分都更加复杂,所以项目需要九个月才能完成。
复杂性是会叠加的,而且不是简单的线性叠加。
这个章节应该仔细、反复阅读。——锅巴GG

测试

  • 测试法则(Law of Testing)

你对软件行为的了解程度,等于你真正测试它的程度。
除非亲自测试过,否则你不知道软件是否能正常运行。


想加入更多乐读创业社的活动,请访问网站→ http://ledu.club
或关注微信公众号选取:

简约之美:软件设计之道_第1张图片
乐读微信公众号

你可能感兴趣的:(简约之美:软件设计之道)