自序 - 学习设计模式的捷径
设计模式的重要性毋庸多言,每一位有经验的程序员都应该熟练掌握设计模式的原理和应用。学习和掌握设计模式,可以说既简单,又困难。如果学习方法对头,掌握了科学的思维(其中最重要的应该是抽象思维和逻辑思维)方法和学习方法,那么学会熟练地运用设计模式就很简单;如果学习方法不对头,那么就会越学越复杂,老也看不懂,不会用,不敢用。
如果你因为读了大名鼎鼎的《设计模式》这本书,就觉得 Design Patterns 很难、很深奥、很难掌握,这完全是一种误解。实话实说,著名的四博士 15 年前的那本《设计模式》并不适合作为初学者的入门读物。学习设计模式应该可以有一种更简单、更轻松、更快捷的方式。所以,除了向大师致敬以外,这也是我想写《大道至简:实话设计模式》这本免费公开网络书的一个原因。
实话:实话比大话好。大话设计模式好,还是实话设计模式好?职业程序员应该少说大话、空话和虚话,多干实事,多说实话和真话,所以张恂认为,实话设计模式比大话设计模式更好。
实话:GoF 的《设计模式》不适合作为初学者学习设计模式和 OOD 的入门读物。凡提 Design Patterns,人们必会从 GoF 设计模式谈起。GoF(Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides 四位博士)的里程碑著作《设计模式》无疑是一本软件工程史上划时代的经典名著,设计模式的开山之作。过去 15 年来它一直被国内外的专业和非专业人士反复地引用、宣讲、解析和解读,导致诠释、演绎 GoF 设计模式的各类佳作也层出不穷,出现了百舸争流、舍我其谁的喜人局面。
然而将近 15 年过去了,当代软件工程无论在 OOD 的理念和方法,还是在 OO 编程语言、实现技术等方面都有了许多显著的进步和发展,《设计模式》中的许多内容已显得老旧。从与时俱进的角度看,我们觉得它不适合作为 21 世纪设计模式初学者的入门读物或教材,它更适合作为一部经典技术历史文献供有经验的程序员、软件工程师和专家们进行参考、研究和收藏。
为什么说《设计模式》不适合作为初级程序员学习的入门教材,我想可能有很多原因。首先,贯穿全书的实例主要围绕一个文档编辑器的开发,还有不少地方介绍的是更为抽象、难懂的文法解释和处理,而如今国内大多数程序员可能都工作在 IT 应用和系统开发领域,包括企业应用、行业信息化、互联网/Web 应用开发等等,估计很少有人会再去从头开发文档编辑器,因而书中的这些应用案例往往不易为普通读者,尤其是初学者所理解和熟悉。
此外,书中的实现代码、举例也主要采用了现在许多年轻程序员所不熟悉的 Smalltalk 和 C++ 等上世纪 80、90 年代流行的旧版本 OO 编程语言。而近十年来一批更为成熟和高级的当代 OO 编程语言(如 Java、C#、VB.NET 等等)和建模技术(如 UML)已经得到了非常广泛的应用,同时也出现了一批相当成熟的主流 OO 框架、重用库和应用开发技术平台,如 .NET Framework、Struts、Spring、JSF 等等。在这些框架、平台中,就大量使用了许多经典和创新的设计模式。如果一本设计模式的入门读物能够结合这些当代的编程语言、技术、框架和平台及其应用进行介绍,必然会增加不少时效性和可读性。
以上列举的这些情况,无疑都增加了《设计模式》这部经典的阅读理解难度。简而言之,尽管 GoF《设计模式》中的 OO 软件设计原理、原则和思想精髓可能永不过时,但是书中的许多内容和例子确实离大家的日常工作
有点远,如果初学者拿这本书作为学习教材或入门读物难免让人有舍易求难、舍简求繁之感。
实话:每一位程序员都应该学习和掌握设计模式。毫无疑问,每一位程序员,无论专业的,还是业余的,都应该学习设计模式。只有掌握并能够熟练运用设计模式,一名程序员才可以称之为现代 OO 程序员。理论上,一名程序员所掌握的各种设计模式应该越多越好,尤其对于一些常见、经典的设计模式更应该烂熟于心,从而遇到自己所从事的应用领域中的任何设计开发问题,都能够迅速拿出成熟的解决方案。
实话:掌握设计模式有诀窍。理解、掌握设计模式真有那么难吗?我们这个世界存在着简单的科学真理,复杂的设计模式表象背后自然也存在简单的客观现实。学习和掌握设计模式有没有什么技巧、窍门和捷径呢?有。
我最喜欢用、极力向大家推荐的第一种科学学习方法是
比较法。在 23 个 GoF 设计模式中,有不少模式存在着相似性,在使用时很容易混淆。通过认真细致的比较,我们不但可以发现一组彼此相似或相关的设计模式之间的真正差异点,而且还可以用一组、一批模式整体学习的方式取代(或弥补)逐个模式孤立学习记忆的方式,从而起到加深记忆、提高学习效率、促进准确运用的效果。
我最喜欢用、极力向大家推荐的第二种科学方法是
图形法建模法(用 UML 记忆、思考和分析设计模式)。学习设计模式切忌死记硬背。最好做到只要一听到某个设计模式的名称,就能迅速在自己的大脑中,投射或浮现出这个设计模式的 UML 标准静态图(如类图)和动态图(如序列图、通信图、状态图等等),这远比直接投射或浮现出一行行的高级程序设计语言源代码要艺术、敏捷和高效得多。
有经验的 OO 程序员知道,设计模式的抽象层次要比具体的 OO 编程语言高一层,用图形化的抽象建模语言来描述设计模式,最简单,也最形象。同一个设计模式,既可以用 Java、C#、VB.NET 实现,也可以用 Delphi、C++、Ruby 或 JavaScript 等其他各类 OO 编程语言实现。所以,企图通过死记硬背程序源代码来记忆设计模式的方式,不但让我们很难看到(或分析、比较)设计模式的本质特征,而且也是非常低效和错误的。
第三种最常用的设计模式学习方法是
比喻法,或叫比拟法、类比法。我们常常可以把设计模式同现实世界中某一个或某一些为人所熟悉的形象比喻联系起来,以便领会和掌握它们的基本结构和特点,加深对模式的记忆和理解。事实上,很多设计模式的名称原本就是一种比喻或对现实世界的模拟,例如,抽象工厂、桥、职责链、中介、访问者等等。熟练地运用比喻法可以产生这样的效果,一听到某个设计模式的名称,脑子里就能马上联想到它的比喻,进而浮现出它的结构图(UML 图形)。
Software is virtual reality(张恂)。比喻法之所以简单而有效,根本原因是因为软件设计活动本质上就是一种建模活动,而且由于我们是人类,我们总是会自觉不自觉地在软件程序中模拟、效仿现实世界中自己所熟悉的各种物质、概念及其运动规律。
通过打比方、比喻、类比,乃至用说俏皮话、调侃和无厘头的方式来学习设计模式,可能是一种不错的学习方式,能够寓教于乐,收到奇效。然而,运用比喻法需要注意的一个问题是:不要滥用比喻。为某个设计模式找到一个非常贴切、形象的比喻并非一件易事。现有很多设计模式比喻的问题是不像,没有抓住模式的基本特征(我也不一定能做得更好)。此外在拿设计模式与现实世界、人类社会作类比的时候,最好也不要扯得太远,以简明为宜。
第四,我认为最重要的也是被许多人所忽视的一个学习要领是:
通用的原则与方法高于具体的模式和做法(General Principles and Methods over Concrete Patterns and Practices)
有没有什么东西比设计模式更重要?有!满脑子只有设计模式是不对的,其实这个世界上比设计模式更重要、更高级的事物还有很多,比方,设计原则和方法,尤其是 OOD 原则和方法,抽象、普适的原则和方法比具体、个别的模式、做法和解法更重要,其实所有的设计模式都是根据某种或某些软件设计的基本思想、原则和方法而创造出来的。
...