附录
我的第一部“靓车”是一部已经使用了8年的标致(Peugeot),这是我大学毕业后不久别人送给我的。有人把这款车称为“法国的梅赛德斯”,这辆车制造精良,驾驶起来非常舒适,而且一直也没出过什么毛病。但到我手里时,它已经有一些年头了,因此到了该出毛病的时候,而且需要更多保养。
标致是一家老牌公司,数十年来一直沿着自己的发展路线前进。它有自己的机械术语、设计和特殊风格,甚至零部件的拆卸有时也不是标准的。这导致标致车只有标致公司的专家才能修理,维修费用对于一个刚毕业的、没多少收入的学生来说是一个潜在的问题。
在一次平常的养护中,我把车开到当地一家机修工那里检查漏油问题。他检查了底盘,告诉我油是“从距离车尾大概2/3位臵处的一个小箱子里漏出来的,这个小箱子看起来与前后轮之间的制动力分配有关”。随后他拒绝了为我修车,建议我去找50英里之外的经销商。任何机修工都可以修理福特或本田汽车,这就是为什么这些车开起来更方便而且维修费用也较低的缘故,尽管它们在机械制造上与标致汽车同样复杂。
虽然我确实喜欢这部车,但我再也不想拥有一部古怪的车了。有一天车被检出了一个问题,而对它的维修费用相当昂贵。我实在是受不了这辆标致了,于是就把车送给了当地一家接受汽车捐赠的慈善机构。然后我买了一辆旧的本田思域,买这辆车的钱跟修那辆标致的费用差不多。
领域开发缺乏标准的设计元素,因此每个领域模型和对应的实现都很奇怪且难以理解。此外,每个团队都不得不重新发明轮子(或齿轮,或雨刷)。在面向对象设计中,所有的一切都是对象、引用或消息,这些都是有用的抽象。但这并不足以约束领域设计的选择范围,也无法支持对领域模型进行简练的讨论。
“一切都是对象”这个观点就好像木匠或建筑师把房屋归纳为“一切都是房间”一样。房间有大有小,有电源插座和水池的大房间可以做饭,也有楼上用来睡觉用的小房间。描述一栋普通的房子可能需要许多页纸的篇幅。建造和使用房屋的人意识到房屋遵循着一些模式,这些模式有具体的名称,如“厨房”。这种语言使人们能够对房屋设计进行简练的讨论。
此外,并非所有的功能组合都是实用的。为什么不建一个既能供我们洗澡又能供我们睡觉的房间呢?这样不是很方便吗?但长期的经验已经形成了习惯,我们把“浴室”和“卧室”分开。毕竟,洗浴设施往往可以与更多的人共用,而卧室则不然。浴室需要最大限度地保证个人隐私,甚至那些共处一个卧室的人也不能未经允许而同时使用这个浴室。而且,浴室需要装备特殊的、昂贵的设施。浴缸和卫生间通常设在一个房间里,因为它们需要相同的基础设施(水和排水管道),而且二者都需要保护隐私。
另一类需要安装特殊设施的房间是我们用来做饭的房间,也称为“厨房”。与浴室相比,厨房没有隐私需求。由于厨房的设计同样很昂贵,因此通常一所房屋(即使是很大的房屋)只有一个厨房。这种单一性也促使我们形成了准备全家共用的食物和共同用餐的习惯。
当我说我需要一所有三间卧室、两间浴室和一个开放式厨房的房屋时,我把大量的信息打包到一句很短的话里,并且避免了很多愚蠢的错误,如把抽水马桶放在冰箱旁边。
在每个设计领域(如汽车、皮划艇或软件)中,我们都会把设计建立在已有模式上,在已有主题范围内即兴发挥。有时我们必须发明一些全新的东西。但是,以标准的模式元素为基础,可以避免把精力浪费在那些已经存在了解决方案的问题上,从而集中精力关注我们的特殊问题。此外,根据传统的模式来建立自己的设计可以避免产生过于特殊的、很难交流的设计。
虽然软件设计领域不像其他设计领域那么成熟,各种情况变化多端,无法像汽车零部件或房屋那样具体地应用模式,但不管怎样都不能仅仅停留在“一切都是对象”这种层次上,至少要分清“螺栓”和“弹簧”。
20世纪70年代,一群由Christopher Alexander[Alexander et al.1977]领导的建筑师提出了一种共享和标准化设计思想的理念。他们的“模式语言”把一些经过事实检验的解决方案组合在一起,用来解决一些公共的问题(这些问题比“厨房”要复杂多了,可能会使Alexander的一些读者望而却步)。他们的目的是让房屋的建造者和使用者用这种语言进行交流,并且在这些模式的指导下建造出优美的建筑物,为房屋的使用者提供实用的功能,并让他们产生良好的体验。
无论建筑师们是怎样想的,这种模式语言已经对软件设计产生了重大的影响。在20世纪90年代,软件模式被应用在很多方面,并且获得了一些成功,特别是在详细设计[Gamma et al]和技术架构[Buschmann et al.1996]方面获得了显著成功。近来,模式被用于描述基本的面向对象设计技巧[Larman 1998]以及企业架构[Fowler 2002,Alur et al.2001]。模式语言现在已成为组织软件设计思想的主流技术。
模式名称应该作为团队语言中的术语来使用,我在本书中就是这样使用它们的。当在讨论中出现模式名时,一律采用了英文小体大写格式,以便于区分。
以下是本书讨论模式时所采用的格式。有的模式与这个基本格式略有不同,因为我喜欢具体问题具体对待,而且我认为可读性比严格的结构更为重要……
模式:模式名称
[概念的说明。有时用一种形象的比喻或引起读者兴趣的文字。]
[上下文。对概念与其他模式相关性的简单解释。有些情况下是一段简单的模式概述。
但是,本书中的大部分上下文讨论都是在每章的引言以及其他叙述段落中给出的,而不是在模式中给出的。
[问题讨论]
问题小结
通过解决问题的讨论形成一个解决方案。
因此:
解决方案小结。
结果。实现考虑。示例。
结论。简单解释这种模式如何引出后续模式。
[实现问题的讨论。在Alexander最初的格式中,这个讨论应该放在一个段落内,描述问题的解决,本书一般是按照Alexander的方法来组织的。但有些模式需要较长的实现讨论。为了保证核心模式讨论的紧凑,我把这些较长篇幅的实现讨论移到了模式讨论的后面。
此外,较长的示例,特别是涉及多个模式组合的示例,也放在模式之外进行讨论。]
