最经典的书籍不一定最容易懂,正如阳春白雪之于下里巴人。在设计模式的世界中,GOF 的《设计模式》永远都是人们推崇的经典,然而真正能够将开发人员引入设计模式殿堂的,或许还是《深入浅出设计模式》(或其他类似书籍)。前者是永恒的经典,后者则是入门的经典。学习一门技术,正需要这样面向不同读者群的两种经典。
领域驱动设计(Domain Driven Design,DDD)同样如此。
作为领域语言的奠基人,Eric Evans 在领域驱动设计的地位,相当于 Eric Gamma 在设计模式中的地位。他的著作《领域驱动设计——软件核心复杂性应对之道》,可谓领域驱动设计的奠基之作。要讨论领域驱动设计,就不可能绕过 Eric Evans;正如要讨论重构,就不可能忽视 Martin Fowler。
那么,有多少初学者可以在一开始阅读该书,就能够很好掌握领域驱动设计的核心概念?我想,能有如此收获的,绝对是凤毛麟角。原因无他,Evans 的讲述过于深奥。如果在领域驱动设计的基础之上,还要加上 Martin Fowler 提出的企业应用架构模式,以及 XP 中的测试驱动开发,我们还能找到一本好书吗?答案是 Jimmy Nilsson 的《领域驱动设计与模式实战》。
Jimmy Nilsson 不一定是一名优秀的设计思想家,但在项目实战方面绝对造诣非凡。软件开发正是这样的一门科学,用最专业、最简练、最准确的语言描述,不一定能让读者醍醐灌顶;阅读几行代码,分析几幅 UML 图,读者反而会触类旁通,有一种豁然开朗的感觉。本书的优秀正在于此。
本书的特色可以从章节的分布窥见一斑。全书分为四部分,分别为:背景知识,应用 TDD、应用 PoEAA 以及下一步骤。
正如书中原文所述,“第一部分是有关布置场景的。”世间万事万物都不可能脱离其上下文而单独存在。领域驱动设计与企业应用架构模式,并不是孤立的两门技术,也不是凭空产生的超级理论,它们离不开软件设计知识的厚积薄发。书中的第一部分是本书的纲领性篇章,内容涵盖架构、领域驱动设计、测试驱动开发、重构、模式与持续集成。
我很喜欢 Nilsson 在书中的示例方式,他总是尝试着给读者几个不同的方案,通过仔细地分析与比较来说明各种方案的优劣。他没有将自己的意志强加于人,而是循循善诱。因为,设计本无绝对正确的方案,不同的应用场景,决定了不同的解决方案。他只是对自己的选择给出恰如其分的建议。例如本书第二章中关于状态模式的实例,就提出了四种不同的解决方案,并以大量的代码来演示其实现。
另外一种好的示例方式是完整,将每个过程都细致地表现出来,从而给人一种真实项目的感受。在第三章中,关于测试驱动开发和重构的示例,正是以完整的案例演示了测试驱动开发的过程。其中包含有对测试的尝试,工具的选择,以及设计的优化。
本书的精华集中在第二部分和第三部分。第二部分关注领域驱动设计,它能够帮助我们正确地建立以领域模型为中心的设计思想。这部分的内容主要介绍了基于领域驱动设计分层中领域层的相关设计。首先通过分层架构模式,廓清了领域驱动设计的架构思想和架构风格。这一点非常关键。如果不明确架构的层次关系,就很容易将领域知识与数据访问混杂在一起,从而导致设计目的的不明确与混乱。所谓“领域驱动设计”,即表明领域是设计的驱动力与导向,如果不能正确地建立以领域模型为中心的设计思想,那么所谓的领域驱动设计,就只能是空中楼阁,或者是“挂羊头卖狗肉”。有过编程经验的开发人员已经习惯于从数据库开始的设计方式,即使明确领域建模的重要性,在设计过程中,数据库总会像一团幽灵一般不停地来困扰我们的思想。在分析领域模型时,我们总是会不由自主地想起,对于这样一个领域实体,在数据表中究竟该如何表示,对象之间的关系是如何通过主 / 外键建立关联的,数据表的字段如何进行数据的存储?……诸如此类的问题,总是会纷至沓来。Nilsson 并不讳言这一点,他自己也经历过如此的转变。正因为这样的宝贵经验,他才能够在书中给予我们正确实施领域驱动设计的真知灼见。
领域驱动设计从来不是一蹴而就的,书中的内容非常准确地表达了这样一个观点。如何精化领域模型,方法就是测试驱动开发。书中的第 5 章完整地描述了这一过程,从编写第一个测试用例,到引入领域模式,细化流程,以及对基础架构实现的考虑。书中的代码包含两部分:测试代码与实现代码;书中的 UML 图也分为两种风格:随手涂鸦的草图和 UML 工具绘制的类图。这样的示例演示过程如此之真实,给读者的感觉不是在阅读书籍,而是亲临项目组,与 Nilsson 一起讨论设计方案,共同推进领域驱动设计。这种阅读感觉是无比美妙的。
勿庸讳言,Martin Fowler 提出的企业应用架构模式并不易于应用,即使是设计老鸟,在选择企业应用架构模式时,也会陷入迷茫、彷徨或者进退失据的境地。Martin Fowler 在设计方面具备的归纳、总结以及抽象的能力已经登峰造极。他总能化腐朽为神奇,或者发现常人所未见的技巧与思想。《重构》如此,《企业应用架构模式》同样如此。然而,令人遗憾的是,《企业应用架构模式》一书虽然有了很好的归纳与分类,但模式种类的繁多仍然会让人无从做出选择,所谓“乱花渐欲迷人眼”。而书中仅限于“玩具项目”的引入,并以片段而非整体的方式进行案例介绍,总会给人一种隔靴搔痒的感觉。Nilsson 的《领域驱动设计与模式实战》正好弥补了这一缺陷。在应用企业应用架构模式时,他仍然延续了第二部分的案例,并结合领域驱动设计的分层模式,重点讲解了在实现基础架构过程中如何应用和选择企业应用架构模式。
当然,本书的这一部分内容还不够完美,因为他主要针对的是领域模式的应用,至于其余企业应用架构模式,例如分布式、并发、服务等诸多内容,则浅尝辄止,颇有几分意犹未尽的感觉。以第三部分的第 9 章《应用 NHibernate》为例,固然考虑了应用和实践,完整地展示了 NHibernate 处理 ORM 的过程;却正因为如此,显得深度不够,没有很好地将企业应用架构模式和领域驱动设计进行深度挖掘,反而像是一篇介绍 NHibernate 入门的低级读物。
事实上,不仅是这一章的内容,整个第四部分《下一步骤》都给人这样的感觉。或许因为这部分内容并非 Nillsson 的创作,使得在叙述风格产生了不统一。当然,这未免有些吹毛求疵了。如果割裂开来看这些内容,每一篇都算得上是介绍软件设计应用与实践的佳作。这些内容涵盖的面也非常广泛,包括 SOA、控制反转与依赖注入、AOP、MVC 模式等内容。我在阅读这些内容的时候,总觉得作者还没有完全把这些内容展开,只能说浮现出冰山一角。这让我感觉不甘。可若是真的能做到这一点,恐怕本书就会变得和砖头一般的笨重了。
回过头再来思考本书,它是面向初学者的入门级读物吗?我想不是。没有足够的设计能力和思想的积累,很难真正读懂本书。但它给予的实践性设计指导,却无疑简化了它的阅读难度。据我的阅读经验来看,若希望掌握领域驱动设计,比较好的阅读途径是:首先阅读 Eric Evans 的《领域驱动设计——软件核心复杂性应对之道》(前提是你了解足够多的设计模式知识,以及与设计相关的知识,例如 UML、重构以及测试驱动开发)。是的,这本书相对较难,我们很难读懂。但我的建议是可以读书“不求甚解”。遇到不明之处,做个标记,然后放过它,以迂回的方式往前走。这其中,可以适当参考 InfoQ 的迷你书《领域驱动设计精简版》,它对实体、值对象、聚合、服务、工厂以及资源库等领域对象和模式的描述实在是简明扼要,令人印象深刻。在对领域驱动设计已经有了比较直观和深入的概念之后,再阅读 Nilsson 的《领域驱动设计与模式实战》一书,你一定会有一种豁然开朗,如曲径通幽的感觉。我想,当你阅读完本书之后,一定会迫不及待地尝试使用领域驱动设计来完善或重构旧有的设计。不过,千万不要奢望从此之后你就能一马平川,真正遇到领域驱动设计相关知识的疑惑,还是需要回头阅读 Eric Evans 的著作。此时的你,一定能从该书中找到你希望知道的答案。
评论