我希望告别冗长的前言,仅述说第二版的变更。写作第二版的我,疯狂地吸收了诸多大师的设计思想,这一点可以从参考文献的前后差别看到端倪。这两年以来,我又参与了几个项目的设计与开发工作,所谓“实践出真知”,在佐证大师观点的同时,自己对设计的认识更进了一步。或许,第二版不会比第一版优秀太多,但至少会减少诸多不足。囿于版本,我无法做出新的突破。我期待能创作一本全新的书,全面论述我对软件设计的认识。现在的我,还不足以写出梦想中的软件设计之道。
言归正传。
整体而言,我对第一版的所有章节都进行了一定程度的修订。或者更正了过去的错误,或者进一步完善了原有内容。本书的内容仍然是散漫而自由的,然而形散而神不散,大体遵循了设计的基本原则。
在第一篇《设计之要》中,我新增了《对象法则》一章,言简意赅地介绍了面向对象思想的核心要素与设计原则。这基于我的一贯理念,即设计模式的核心本质是面向对象设计思想的运用。只有掌握了面向对象设计思想,才能真正体会设计模式的精髓,并将其运用在实际的项目开发过程中。《对象法则》一章可以有机地与《封装变化》一章结合起来,再加上第23章《软件体系架构》的内容,基本上勾勒出软件设计的脉络,从面向对象思想到设计模式,再到软件体系架构。
在《封装变化》一章中,我不仅完善了项目实例,还增加了关于如何“解耦具体依赖”的几种技巧。对于软件设计而言,这是非常有益的指导。我整个儿删去了第一版的第5章《设计,由你掌握》,并将其中的部分内容转移到《封装变化》一章中。这使得第一篇的内容更为紧凑,虽然删去了讨论极限编程的相关内容,却可以使得我们能够更加关注于设计,而不是方法学。
第二篇《.NET框架与设计模式》增加了对.NET 3.X的源代码分析。我无法做到与时俱进,因为.NET 4.0即将走进.NET开发人员的程序生活。或许在本书出版之后的不久,还会有5.0,6.0……我只是希望我的书不要被时代抛弃得太远。好在设计模式本身属于经典,而经典总是能够经得起时间考验的。本书讲述经典,自然能讨得一定好处。
更新最明显的是迭代器模式在.NET中的实现。C# 2.0引入的yield return以及.NET 3.0引入的Lambda表达式都为迭代器模式在.NET中成为一种惯用法贡献了一份心力。我对此的分析,可以在一定程度上帮助读者更好地理解迭代器模式。在第二篇中,我新增了一章《.NET中的命令模式》,通过解析.NET 3.0引入的WF(Windows Workflow Foundation),展现命令模式的非凡价值。第二篇的内容虽然与.NET平台息息相关,但对于其他平台的开发人员而言,仍有可观之处。我在撰写本书第二版时,同样参考了Java平台的设计理念,以及Ruby中的设计模式。
从章节名称来看,我对第三篇《媒体播放器的设计之旅》进行了颠覆性的革新。事实不然,虽然内容仍有调整,但并未动摇其根本。在对本篇进行修订时,我扮演了一名重构者的角色,利用重命名和搬移内容的方法,极大地改善了既有章节的合理性。我抛开原有的以设计模式为核心的论述方式,转而从软件设计的角度看待问题。模拟真实的软件开发,我讨论了如何运用面向对象设计思想,如何对接口进行分离。当客户需要引入第三方软件时,我提出了接口适配的方案。当需求发生变化时,我则对接口行为进行了扩展或装饰。
第四篇《设计模式应用实践》仍然体现了本书的重要价值。我对第18章《命令模式应用》的实例进行了极大地完善,使得该实例在表现命令模式方面,更加丰富与完整。第19章《职责链模式应用》完全面貌一新,替换为最近完成的一个项目实例,并通过对领域进行建模,辅以用例图、时序图、通信图和类图推导详细设计,展现了“用例驱动开发”设计思想的冰山一角。
本书对软件架构着墨不多,主要的架构思想均放在第五篇《.NET体系架构》中。利用PetShop实例,对于指导读者初窥架构之美,仍有不可低估的作用。第二版对软件体系架构的内容有所补充与增强,更多地引入了企业应用架构模式和领域驱动设计的内容。第23章《软件体系架构》算得上是技术架构的入门读物,主要介绍了分层架构模式与相关设计要素。在第24章《数据访问层》中,我特别引入了.NET 4.0中的Entity Framework,算是一次有益的尝鲜。利用这样的ORM框架,还可以极度方便地实现资源库模式与工作单元模式,在诸多分层架构中,我们都可以看到它们的身影。在第28章《表现层》中,我设想了如何在PetShop中引入ASP.NET MVC框架。我本希望能有大量篇幅介绍Silverlight,以及MVP模式的运用,如此对于.NET的表现层设计方才显得完整,可惜我对Silverlight所知不多,心有余而力不足。
第二版还有诸多变化不能体现在目录中。例如我对本书的全部设计图进行了更新,更加准确、完善和美观,并保持了图形风格的一致性。第二版加入了诸多注解,大多数内容都是正文的补充与扩展,乃至思想点滴。阅读这些注解,可以帮助读者更好地理解我的设计意图,获得更多的模式知识。
本书面对哪些读者?读者又该如何阅读本书?第一版前言已经给出了答案。本书的再版并不打算彻底地改头换面。除了致谢,我不打算重复唠叨了。
钱锺书先生认为,献书仿佛魔术家玩的飞刀,放手而并没有脱手。随你怎样把作品奉献给人,作品总是作者自己的。可我还是希望把本书献给我的孩子——子瞻。当他宁静地呆在母亲肚子里时,本书的第二版同样也在孕育之中。现在,子瞻已经过了周岁生日,没有什么礼物可以比得上这本书更让我感到自豪。我还要把本书献给我亲爱的妻子。写作虽然痛苦,可哪里及得上你分娩痛楚的万分之一。抚养子瞻的辛劳,更让虚弱的你身心憔悴。本书献给你,可否给你一丝安慰?
感谢我的父母。尤其感谢我的母亲。这一年多以来,调皮的子瞻折磨得您腰酸背痛,您却没有任何怨言,反而甘之如饴。我能有时间写作本书,您功不可没。