前 言

程序的复杂度将随程序的演化而递增,除非采取措施来保持或降低复杂度。
——雷曼的复杂度递增定律 [1]

关于本书

改变很难却又不可避免,生活如此,软件亦如此。为满足用户不断增长的需求,软件必须不断演化。鉴于软件的无形特征,要管理这种不断的变化很难。其典型的结果是软件质量低下①和巨额技术债务。

本书介绍如何通过发现和消除设计中的坏味来改善软件质量和减少技术债务。医疗领域有种说法:“好医生熟悉药品,而伟大的医生熟悉病症。”套用这种说法,“好的设计人员熟悉设计解决方案,而伟大的设计人员明白设计中的问题(坏味)、导致问题的原因,以及如何应用成熟合理的设计原则来解决问题”。本书基于此理念,旨在引领你成为更优秀的设计人员,能够识别和理解设计中存在的“病症”,并能采取妥善的“治疗”措施,进而改善软件质量,保障技术债务可控。

本书主要内容

本书介绍了 25 种结构型设计坏味及其有助于管理技术债务的重构建议。我们认为遵循软件设计原则是开发高品质软件的关键。鉴于此,我们根据 4 个基本设计原则来组织本书介绍的坏味。根据坏味违反的具体原则对其进行命名。介绍每种坏味时,我们都指出了它违反的原则,讨论了一些可能导致该坏味的因素,并列出了该坏味可能影响的重要质量指标,让读者知道设计欠下的技术债务。

① Capers Jones[3] 发现,糟糕的软件质量在美国每年的花费超过 1500 亿美元,在全球每年的花费超过 5000 亿美元。

描述每种坏味时,我们还提供了真实的示例以及基于行业项目经验的趣闻轶事;对于每个示例,都提供了消除其坏味的可能的重构解决方案。我们认为,要判断坏味的影响,必须考虑设计的具体情况。因此,我们也介绍了由于条件限制(如语言或平台的局限性)或出于大局考虑而有意识地引入坏味的情形。

根据粒度的不同,坏味可分为架构级坏味和代码级坏味;根据性质的不同,坏味又可分为结构型坏味和行为型坏味。本书并不会介绍各种粒度和性质的坏味,而是主要探讨结构型设计级坏味。另外,本书只讨论有文献记载且常出现在实际项目中的坏味。


目标读者

软件架构师和设计人员。如果你是软件架构师或设计人员,你将是本书的最大受益者。本书将从多个方面给予你帮助。作为架构师和设计人员,你的主要职责是负责软件设计及其质量,因此比其他任何人都更想知道软件的质量需求。本书介绍的设计坏味和重构建议知识无疑将提供这方面的帮助—— 你可直接使用这些知识来改善设计质量。本书明确阐述了坏味对重要质量指标的影响,让你能够更深入地认识到,即便是微不足道的设计决策也可能给软件质量带来重大影响。通过真实的趣闻轶事和案例研究,你将认识到为避免坏味的出现,需要注意哪些因素。

软件开发人员。我们观察到,开发人员喜欢走捷径,这些捷径看似可以帮助完成工作,却会降低设计质量。我们还注意到,如果设计方案未对某些方面做出明确的规范,那么开发人员就会在编码期间做出一些重要的设计决策。在这种情况下,如果没有正确地应用设计原则或根本不应用设计原则,坏味就会出现。我们深信,通过阅读本书开发人员将认识到,即便是看似无关紧要的设计决策或捷径,也可能严重影响软件质量。有了这种认识,开发人员将能够发现并解决设计和代码中的问题,成为更加优秀的设计人员。

项目经理。项目经理总是担心项目不能按时完成或超支。当前,越来越多的人认识到,导致这些问题的主要原因是技术债务,因此很多项目经理都在不断寻找减少技术债务的解决方案。这样的项目经理将受益于本书。通过阅读本书,他们将对设计中可能出现的问题有更深入的认识,进而更加重视重构。

学生。本书内容与讨论软件设计的计算机科学或软件工程课程紧密相关。软件设计课程的重点之一是指导高品质软件建模和设计的基本原则。一种学习这些原则的有效方法是,先研究错误应用设计原则的后果(即坏味),再学习如何正确地应用它们(即重构)。因此我们认为,阅读本书有助于学生明白遵循良好设计原则和实践的重要性,进而能够在实际项目中提供高品质设计。


阅读前提

最好你能具备基本的面向对象编程和设计知识,并至少熟悉一种面向对象语言,如 C++、Java 或 C#;另外也最好熟悉面向对象概念,如类、抽象类、接口(它们统称为抽象或类型)、继承、委托、组合和多态。


本书结构

本书按照逻辑划分为如下三部分。ˆ

第 1 章和第 2 章介绍相关的背景知识。第 1 章介绍技术债务的概念、引发技术债务的因素以及技术债务对软件项目的影响;第 2 章介绍设计坏味,描述本书给设计坏味分类和命名时采用的基于原则的分类方案。ˆ

第 3~6 章介绍 25 种设计坏味。这 4 章组成了一个坏味目录,它们分别对应坏味违反的 4种基本原则:抽象、封装、模块化和层次结构。介绍每种设计坏味时,都将提供说明性示例,阐述坏味对重要质量指标的影响,讨论消除示例中坏味的可能的重构解决方案。ˆ

第 7 章和第 8 章反思我们所做的工作并介绍如何偿还项目的技术债务。第 7 章以坏味目录中的一些坏味为例,阐述了坏味与设计的其他部分之间的相互作用。第 8 章就如何在实际项目中重构坏味以管理技术债务,提供了一些实用指南和技巧。

附录列出了本书提及的设计原则以及可帮助检测和消除设计坏味的工具,概述了本书使用的类似于 UML 的表示法,列出了有助于拓展软件设计知识的推荐读物。

考虑到 Java 是当前使用最广泛的面向对象语言,我们提供的都是 Java 编码示例。然而,重要的经验教训都是基于设计原则的,因此对 C++ 和 C# 等其他面向对象语言来说也适用。另外,本书使用了类似于 UML 的简单类图,这在附录 C 进行了解释。

本书讨论的很多示例都摘自 JDK 7.0。我们对 JDK 中的坏味进行了解读,这种解读基于通过分析源代码和注释获得的有限信息。JDK 中出现这些坏味,也许有很充分的理由。在本书中,我们分享了大量的趣闻轶事和案例研究,它们来自于:ˆ

在线坏味论坛(Smells Forum)参与者分享的经历,我们建立这个论坛旨在从社区收集坏味故事;ˆ

会议、讲座、培训、社区论坛的参与者与我们分享的事件和故事;ˆ

图书、期刊、杂志和其他在线出版物;ˆ

本书作者担任设计评估和重构独立顾问的经历。

需要强调的是,我们无意通过这些趣闻轶事、案例研究和示例来指责任何软件企业及其设计中的坏味,而只是想让软件工程师了解软件设计中可能存在的问题。鉴于此,在本书的趣闻轶事和案例研究中,我们对一些细节做了适当的修改,以免透露企业名称、项目名和产品名等私密信息。

你不必从头到尾逐页阅读本书,可查看目录并直接跳到感兴趣的章节。


获取更多信息

要 获 悉 本 书 的 更 详 细 信 息, 请 访 问 Elsevier Store 网 站(http://www.store.elsevier.com/product.jsp?isbn=9780128013977);要获取更多的信息、补充材料和资源,请访问 http://www.designsmells.com;如果你有任何建议和反馈,请通过 designsmells@gmail.com 与我们联系。


为何编写本书

软件设计天生就是一项复杂的工作,要求软件工程师对设计原则了如指掌,并具备丰富的经验和技能。你必须细致地考虑和分析需求,确保对它们有深入的认识。然而,当今的软件工程师必须在很短的时间内打造出非常复杂的软件,还要面对不断变化的需求。在这种情况下,要确保设计和整个软件的质量无疑是巨大的挑战。

鉴于此,我们决定承担起帮助软件工程师改善设计和软件质量的任务。我们最初的努力方向是开发一种方法,用于评估行业软件的设计质量(并以论文 [4] 的方式发表了研究成果)。我们调查了大量软件工程师,试图了解他们在项目设计期间面临的挑战。调查表明,虽然很多软件工程师掌握了重要设计原则的理论知识,但不清楚如何实际应用这些原则,结果导致其设计中出现了坏味。

我们的调查还揭示了一个重要的洞见:可利用设计坏味来帮助理解软件工程师在应用设计原则时所犯的错误。鉴于此,我们开始了一次“长途旅行”,旨在研究并了解设计中出现的各种坏味。在此期间,我们发现了散落在各种资料(包括图书、文章、论文和工具)中的坏味,并将它们记录下来。最终收集的坏味多达 530 种!

我们原本希望这种研究可帮助我们更深入地了解坏味。结果也确实如此,但此时我们面临着一项艰巨的任务—— 搞懂收集到的大量坏味。鉴于收集的坏味如此之多,我们决定只考虑那些实际项目中常见的结构型设计坏味。接下来的任务是,以有意义的方式对这些坏味进行分类。我们尝试了多种分类方案,但都不满意。在尝试过程中,我们逐渐意识到,要对这些坏味进行组织,以便与架构师、设计人员和开发人员分享时能够给他们提供帮助,分类方案必须与基本设计原则相关联。这让我们获得了如下洞见:

从违反了哪些底层设计原则的角度来看待每种坏味时,我们对该坏味将有更深入的认识;更重要的是,这也自然而然地指出了消除该坏味的潜在重构方法。

基于这个颇具启发性的洞见,我们采纳了 Booch 提出的基本设计原则—— 抽象、封装、模块化和层次结构,将它们作为分类框架的基础。我们根据坏味主要违反了哪个设计原则对其进行分类、合并,并创建了一个包含 27 种坏味的目录。我们通过论文 [5] 发布了这项初始成果①,当一些论文审阅人建议我们将这项成果扩展为一部著作时,我们受到很大的鼓舞。在此期间,我们还开始向公司提供设计坏味方面的培训,并注意到软件从业人员认为我们的坏味目录确实很有用。受到论文审阅人和软件从业人员正面反馈的鼓舞,我们决定将这项初始成果扩展为一部著作。

本书旨在提供一个框架,帮助你明白违反设计原则是如何导致坏味的,以及如何重构坏味以管理技术债务。根据我们的经验,要成为更优秀的设计人员,关键是利用坏味来明白如何在实际工作中有效地应用设计原则。这是我们想通过本书表达的中心思想。

在研究设计坏味和编写本书的整个过程中,我们始终乐在其中,但愿你也享受阅读本书的过程!

① 这篇论文一共总结了 31 种坏味。—— 编者注

目录