分析模式:可重用对象模型》

前言和介绍(笔记版)

Martin Fowler

翻译整理:Windy J(windy.j@163.com)

 

注:本文采用意译的方法,重在表达原文的意思,而不是逐字逐句的翻译,如有错误,请指正。

前言

不久以前市面上还没有关于面向对象分析和设计的书籍,但现在这类的书非常多以至于人们无法全部一一掌握他们。大部分的这些书致力于讲解一种注记方法,介绍一个简单的建模过程,并提供一些简例来说明。但分析模式:可重用对象模型显然不同,它关注的主要是建模的结果——那些模型本身,而不是关注建模过程——怎样建模。

我是一个信息系统面向对象建模咨询/顾问人员,为客户提供建模人员培训和项目指导。我的绝大部分经验来自建模技术知识和怎样运用它们。不过,更重要的是我在实际建模中的经验,以及看到问题经常会重复出现,正是因为这样我可以重用以前建立的模型,改进它们,并用于新的要求。

最近几年越来越多的人们发现了这一现象。我们意识到典型的方法学的书,尽管很有价值,却只提出了学习过程的第一步,这样的学习过程,还必须捕捉实际的事物本身。这样的意识发展成为了“模式(Patterns)”运动,但是怎样给模式下一个唯一的定义呢?我的定义是:模式是一种思想,它已经适用于一个实践环境中,并有可能适用于其他的环境。(A pattern is an idea that has been useful in one practical context and will probably be useful in others.)模式可以有多种格式,每一种格式都增加了一些有用的特别化特征。

本书讲述分析中的模式,也就是反映商业过程的概念模式,而不是具体的软件实现。大多数的章节讨论不同的问题域中的模式,这些模式难以按传统的行业分类(例如制造、金融、医疗保健等),因为他们经常适用于多个领域。模式可以帮助我们理解人们对世界的认识,而且基于这样的认识来建立计算机系统,并试图改变这些认识(或者可以称为商业过程重组工程Business Process Reengineering——BPR)是非常有意义的。

当然,概念模式(Conceptual Patterns)并不能孤立存在,对于软件工程人员来说,只有当他们看到如何实现时概念模型才有意义。所以在这本书里我还提供了可以将概念模型实现成软件的模式,并将讨论该软件如何适合一个大型信息系统的结构,还将给出和这些模式有关的具体实现技巧。

建模人员将在这本书里找到在其他新的领域里有用的思想,这些模式包括有用的模型,设计背后的理由,还有什么时候适合和不适合应用。这些可以帮助建模人员在遇到具体的问题时更好地应用这些模式。

这本书里的模式还可以用来回顾已有的模型——来看其中哪些可以省略,哪些可以找到替代的方式来改进它们。当我回顾一个项目时,经常拿它们和从以前的项目中学到的模式相比较,就这样,我发现模式意识使我更容易应用以往的实践经验,这样的模式也远远比简单的课本更容易揭露模型的要点和本质。通过讨论我们为什么这样建模,将会使我们对如何改进这些模型有更深的理解,即使我们并没有直接运用这些模式。

本书结构

这本书分为两大部分:第一个部分讲述分析模式——来自概念商业模型的模式;他们提供来自贸易、测量、记帐(Accounting)、组织关系等多个问题域的关键抽象。这些模式之所以是概念性的因为他们关注的是人们对业务的思考和认识,而不是计算机系统的设计方法。这个部分的章节着重于可用的可选模式,和这些可选模式各自的优点和弱点。而且尽管每一个模式可用于特定的问题域,那些基础的模式还可以用于其他的领域。

第二个部分讲述支持模式,通过支持模式对这些分析模式提供使用帮助。支持模式描述分析模式怎样适合一个大型信息系统的结构,描述这些概念模型如何转换成软件接口和实现,还有那些特定的高级(advanced)模型构造怎样和更简单结构相关。

为了描述这些模型,我需要一种注记方法。附录中包括对本书所用注记方法的简要讨论,以及符号的意思,还包括哪里可以找到我所用(注记)技术的指南。

每一个部分都划分为章节,每个关于分析模式的章节包括那些在一个松散的主题空间相关的模式,这些模式也会受到产生它们的项目的影响。这样的组织方式说明任何模式都来自于实际的环境。每个模式出现在一章的各个小节,不象其他模式作者一样,我并没有为每个模式提供单独的标题,而是提供了一个类似于描述原始工程的格式,并增加了模式在原始问题域中以及在其他的环境下如何应用的例子。关于模式,其中最大的困难就是如何抽象到别的问题域;不过我认为这个问题最好留给读者自己去思考。

因此,这本书可以当作一个目录,而不是需要从头到尾读完。我努力使得每个章节独立于其他的章节,(虽然这经常是不可能的,所以每个章节如果引用了其他的章节,我会在介绍里声明。)每个章节的介绍部分包括该章节的通用主题空间,总结这个章节中的模式,以及模式产生的项目资料。

怎样阅读本书

我建议先详细阅读第一章,再看每章的介绍部分,然后就可以按照你的兴趣选择阅读各章,不管你用什么顺序。如果你不熟悉我建模的方法,或我采用的注记和概念,可以阅读附录。在模式表格中给出了每个模式的简要总结,以后回顾本书的时候可以查阅它们。非常重要的是这些模式在它们产生的问题域之外也非常有用,所以我建议你阅读那些也许不在你兴趣之内的章节,例如,我发现医疗保健行业中关于观测和测量的模式在公司金融分析中证明非常有用。

谁将阅读这本书

最大的读者群应该是面向对象计算机系统的分析和设计人员;

一个小规模但非常重要的读者群应该是那些建模项目的问题域专家;

希望程序员们可以钻研这本书,尽管本书缺乏代码和有着概念倾向,我建议你们着重注意第十四章,这一章讲述了概念模型和结果软件之间的关系;

数据建模人员;

经理们将发现这本书是开发活动的一个起点。从模式开始有助于简化目标,项目计划也可以获益于广大的模式设计背景;

学生并不是我定位的读者,但他们同样可以阅读这本书。

一本动态的书

书出版之后作者将难以改变书的内容,但是我一直在努力学习,而且这样的学习一定会改变我的原有的看法,所以我希望这些改变也能让读者们知道。

幸运的是Addison-Wesley公司为这本书提供了一个网址<http://www.aw.com/cp/fowler.html>,将用来提供更多的资料。使得这本书可以保持动态改变,我希望该网址会包括以下内容:

l         我学到的关于这本书的模式的新的东西;

l         对于这本书的问题解答;

l         其他人关于模式的有用解说;

l         UML注记出现的时候我会重画书中的图表并上载它们;

这个网址将是本书的补充部分,所以别忘了关注它,并可用来告诉我怎样改进和发展本书的思想。

答谢(

参考

1.Martin, J., and J. Odell. Object-Oriented Methods: A Foundation. Englewood Cliffs, NJ: Prentice-Hall, 1995

第一章          介绍

1.1    概念模型

大部分面向对象建模的书都提到分析和设计,但对于分析和设计的分界点却一直没有达成统一的意见。在对象开发过程中一个重要的原则是需要设计软件,并使得软件的结构反映问题的结构,这项原则的一个结果是从分析和设计产生的模型结束时都有意变得十分类似,从而导致许多人认为这两者之间没有区别。

我相信分析和设计之间的分别仍然存在,但它正日益成为一个重点。进行分析时你需要努力理解面临的问题,对于我来说这不仅仅是用用例列出所有的需求。在系统开发中虽然用例即使不是必需的,也是很有价值的一个部分,但捕捉完它们并不意味着分析的结束。分析还包括深入到表面需求的背后,来得到一个关于问题本质的精神模型(或理论模型:Mental Model)。

例如有人需要开发一套软件来模仿桌球游戏,问题可能用用例来表述表面的特征:“游戏者击中白球,它以一定的速度前进,并以特定的角度碰到红球,于是红球在某个特定的方向上前进一段距离”。你可以拍下几百个这样的事件,测量不同的球速,角度和距离,但靠这些样例要写出好的仿真程序远远不够,因为除了这些表面现象,你还必须了解背后的本质,那就是和质量有关的运动定律,速度,动量,等等。了解这些规律将更容易看到软件可以怎样建立。

桌球问题非常例外,因为那些定律早已成为公理。在许多企业中,规律并没有得到很好的理解,而需要我们努力去发现它们。因此我们建立一个概念模型来理解和简化问题。某种概念模型是软件开发过程中必要的一部分,就连最不受控制的黑客们都这样做,差别只是:建立模型到底是它本身的一个过程还是整个软件设计过程的一部分。

别忘了概念模型是一个人工产物,它们代表了现实世界的模型,但它们是人类创建的。在工程方面,模型让我们更好地理解现实世界,而且,建模人员也可以使用一个或更多的模型。例如,桌球问题中,人们可以采用牛顿模型或爱因斯坦模型,只是它们的精确程度和复杂程度不一样。

建模原则  模型没有对错之分,只有适用性不同。( Models are not right or wrong; they are more or less useful.)

模型的选择影响着结果(系统)的灵活性和可重用性。在系统中考虑太多的灵活性将使系统复杂度提高,这是不好的设计。设计需要在建造和维护代价上进行折衷。要得到满足某种目的的软件,你需要建立一个和需求相应的概念模型。你需要你能得到的最简单的模型,不要为你的模型增加不可能用到的灵活性。

最简单的模型不一定是你首先需要考虑的,因为简单的方案需要不少的时间和精力。但这些时间和精力往往是值得付出的,它们不但使得系统易于建立,更重要的是易于维护和将来易于进行扩展。所以值得用可以运行的更简单的软件代替原来运行的软件。

你将怎样表达概念模型?很多人把概念模型建立在他们的开发语言中。好处是你可以执行一个模型来验证它的正确性,和进行后续的研究。另一个好处是你最终将把模型转到开发语言,所以可以省区翻译转换工作。

坏处是,很容易陷入语言细节而忘记原本要面对的问题;还有很容易为特定的语言建模,使得模型向别的语言移植变得困难。

为了避免这些问题,许多人开始采用分析和设计技术,这些技术可以帮助人们关注概念上的而不是软件设计上的问题,问题域专家们也容易学会这些技术,由于它们使用图形,因而显得更有表现力。它们可以是精确/严格的,但并非必要如此。

我采用分析和设计技术的一个主要原因是为了和问题域专家一起工作,因为在概念建模时必须有问题域专家参与。我相信有效的模型只有那些真正在问题域中工作的人才能建造出来,而不是软件开发人员,不管他们曾经在这个问题域工作了多久。不过,当问题域专家开始建模时,他们需要指导。我曾经为客户服务监督、医生、护士、金融商货和公司财务分析员教授面向对象的分析和设计技术,同时,我发现,对于他们来说,有没有IT背景其实是无关紧要的,例如,我知道的最好的建模人员是伦敦一家医院的外科医生。作为一名专业的分析家和建模人员,我给这个过程提供有价值的技巧:我提供严格(的标准),我知道怎样使用这些技术,而且我“局外人”的眼光可以质疑模型中看似正确的地方。但是,这些是不够的,在建立分析模型时最重要的是专业知识。

分析技术倾向独立于软件技术,理想情况下,一种概念模型技术最好完全独立于软件技术,就象运动定律一样。这种独立性可以防止技术阻碍对问题的理解,而且产生的模型对各种不同的软件技术一样有用。但是实际上这种纯度不可能达到,例如,(实现)语言的变化也会影响到我们建模的方法。

在这里希望大家注意的一点是,概念模型更接近软件的接口(Interfaces)而不是软件实现(Implementations)。面向对象软件的一个特点就是接口从实现中分离,但在实际中很容易忘记这一点,因为通常的语言在这两者中没有显式的区别。软件组件的接口(它的类型:type)和它的实现(用以实现的类)之间的区别非常重要,《设计模式》一书许多基于委托的重要模式就依赖了这种区别,因此,当实现模型时也不要忘了这些区别。

建模原则  Conceptual models are linked to interfaces (types) not implementations (classes)。

1.2    模式的世界

最近一些年,模式成了面向对象界最热门的话题。它们引发了巨大的兴趣和普遍的宣传。我们也看到一些争论,其中就包括:模式到底是什么;当然难以下一个一般的定义。

模式运动有着不同的起源。近年来越来越多的人发现软件界不善于描述和利用好的设计实践经验。方法学家多起来了,但他们定义了一种描述设计本身(而不是描述实际设计方法)的语言。仍然缺乏描述基于实践设计的技术论文,这些论文可以用于教育和鼓励。象Ralph Johnson和Ward Cunningham提出的:“哪怕有了最新的技术,项目也会因为缺乏一般的解决方案而失败”

模式也从不同的起点发展而来,例如,来自亚历山大·克里斯托弗的思想,来自为软件体系结构编写的手册,来自C++的习惯用法等。

94年《设计模式》一书的出版和Hillside Group关于PLoP(“编程模式语言”)的会议带来了模式运动更广泛的知名度。

当然,软件模式思想并不局限于面向对象技术。

1.2.1  亚历山大·克里斯托弗

许多人看来,软件界出现模式这个词完全是由于亚历山大·克里斯托弗的工作,亚历山大·克里斯托弗是位于伯克利的加利福尼亚大学的一位建筑学家。他发展了一系列建筑学上的模式理论并出版了多部著作。

不过也有很多人否认亚历山大·克里斯托弗在软件模式运动发展中的中心地位,例如,《设计模式》一书的四个作者中有三个在写书之前并不了解亚历山大·克里斯托弗。

1.2.2  文字格式

模式写作的一个显著特征是它遵循的描述格式。一些人遵循亚历山大提出的格式,还有一些人则采用了《设计模式》中的格式。

通常来说,一个模式,不管它怎么编写,有四个必要部分:模式适用的上下文context)陈述;模式提出的问题(problem);形成解决方案过程中的约束(forces);对这些约束的解决方案(solution)。这种格式带标题或者不带标题,但是是许多已经发布的模式的基础,这种格式很重要因为它支持对模式的如下定义:“在一个上下文中对一种问题的解决方案”。——一种定义限定模式为单一的问题-解决方案型。

一种固定格式使得模式和一般的软件技术作品显著区分开来,但固定格式也有它的缺点,例如在这本书中,我经常发现找不到问题-解决方案这种相应关系来说明一个模型单元;而且本书的几种模式都描述了对单个问题的不同解决方式,取决于不同的考虑/代价。

关于模式格式的另一项原则我毫无保留地表示赞同,那就是:模式需要命名。好处是可以丰富开发词汇,设计思想可以得到沟通。再一次强调,这不是模式独一无二的特点,这是技术作品为概念打造术语的常规做法,不过寻找模式促进了这一过程。

1.2.3  作者的抽象级别

模式产生于日常开发而不是学术发明。本书中所有的模式都是一个或多个实际项目的结果和项目中精彩部分的描述。

相信这些模式对别的开发者有所帮助,它们通常不只适用于模型本身的领域,而且经常在其他领域一样有用。例如9.2节中的portfolio模式,最开始作为金融合同分组而创建,但是,通过定义一个隐含的查询,它可以用来分组任何对象,并抽象到可以用在任何问题域中。

那么我面临的一个问题是我应该作何等程度的这类广泛抽象。如果我发现一个模式可以用于更多的问题域,那么我该让它变得有多抽象?问题是如果抽象一个模式,在使其超越原本的问题域时我不能保证它的有效性。所以我认为你必须判断模式对你的问题域是否有用,这一点你比我肯定,或者你已经接触到相当多的问题域专家。任何超出原始问题域的模式的使用都是实验性的,但是它们可以激发你的想象力,让你问自己:“对我确实有用吗?”

1.3    本书中的模式

模式来自实际项目中具有通用性的部分,所以,可以说发现模式,而不是发明模式。

本书中的模式分为以下两类:

分析模式:一组概念,代表业务建模过程中的公共结构,可能只和一个问题域有关,也可能扩展到其他的问题域。分析模型是本书的核心。

支持模式:本身有价值的模式,在这本书里扮演特别的角色,那就是:描述怎样选择分析模型,怎样应用它们,使它们真正实用。

1.3.1  具体建模样例

离开上下文环境,有很多问题难以理解并需要建模人员有相关的建模经验。而模式提供了一些好的方法来面对这些问题。本书中的许多模式通过考察一个领域中特定的问题来处理通用的建模结果,这样易于理解。例如,可以连接到单一对象实例的方法的处理(6.6节);状态图的图表类型(10.4节);模型的知识层和操作层分离(2.5节);通过查询利用portfolio模式分组对象(9.2节)等。

1.3.2  模式来源

如上所示,本书的模式都基于我在大型企业信息系统应用面向对象建模技术的个人实践,也就是说,模式来自我曾经参与的项目。

我希望这本书跨越不同领域并形成交叉,所以我描述了多个问题域的模型,但我没有详细讨论模型的细节,一部分是由于客户机密的原因。

对于这些模型我并非完全自信,由于几个原因我作了一些改动。我简化了一些抽象;保留了原来的精神但让它更容易解释和接受。我还在一些具体的问题域上对一些模型进行了一些小小的抽象。有些情况下我改动了模型来反映我的意见。

对于模式的命名,我采用了用原项目命名的原则。

1.3.3  跨域模式

不管你工作在哪一个领域,我希望你学习你的领域以外的模式。本书的大部分内容包括通用建模要素和建模领域外可用的经验。其他领域的知识有助于抽象。很多专家不象我这么幸运,可以工作在多个领域。在不同领域考虑模型经常会在不相关的环境中蹦出新的主意。

我怀疑有一小部分高度通用的(商业)过程绕过了传统的系统开发和业务工程边界,诊断和治疗模型就是一个;另一个是记账和盘点模型(见第6章)。许多不同的业务可以共用一组相似的抽象过程模型。这对工业界各行业原来发展垂直类库的希望引起了一些大问题。我相信真正的业务框架会沿着抽象概念过程而不是传统的业务线来组织。

1.4    概念模型和业务过程重组工程(BPR)

读者可能认为本书中的概念模型是为了帮助开发计算机系统,其实它们还有其它的用途。好的系统分析员早就知道,采用一个已有的过程,并简单地将它计算机化并不是一种好的做法,计算机可以让人们以一种不同以往的方式办事。但是这种思想并不容易被人们接受,因为系统分析员们的技术好象还是太依赖于软件思考方式。如此看来,IT业的人们还需要一段艰难的时间才能让商业领袖们理解这样的思想。

Jim Odell 的合作经常让我陷入到业务建模而不是软件建模;John Edwards在BPR成为一个热门称号的很久以前就把他的方法叫做“过程工程”(process engineering)。用面向对象技术进行概念建模可以让系统分析和BPR变成同一回事。我所教授的问题域专家们很快掌握了它潜在的功能,并且开始用一种新的方式思考他们自己的领域。只有问题域专家们才能真正使用和应用这些思想。

因此本书中的模型在讲述软件建模技术的同时也讲述了业务工程(business engineering)。尽管业务工程的重点是关于过程(process),这些模式的一大部分是静态类型模型,这样的主要原因是我在涉及的领域:在医疗保健领域我们发现尽管我们建立通用类型模型,应用到这个领域的各个部分,却很难建立多的通用动态模型。

类型模型非常重要,我喜欢把它们当作业务定义的语言,这样的模式提供了一种方式,带来有用的概念,并使这些概念成为大量过程建模的基础。Accountability的概念证实在医疗保健行业中的保密政策建模时很有用,在薪酬管理中我也看到建模改变了这个过程的语言和对这个过程的理解。

1.5    模式和框架

如果随便问一个专家面向对象技术的主要好处在哪里,答案通常是重用reuse)。软件界的美好愿望是有一天开发者可以利用实验和测试过的可用组件来组装系统。不过很多这样的愿望实现得很慢,可以说重用才刚刚开始,更多的是在GUI开发和数据库交互上,还没有出现的地方是在业务级。

在医疗保健、银行、制造业或其他行业没有组件,是因为在这样的领域没有标准的框架(framework)。为了达到信息系统的组件重用,必须建立通用的框架。一个有效的框架不能太复杂,也不能太松散,应该基于一个大问题域的有效概念模型并可以跨越问题域广泛应用。建立这样的框架非常困难,不管在技术上还是在政策上。

本书不打算为不同的工业领域定义框架,而是描述一种状况下的可选建模方法;框架是关于选择一种特定的模型。希望这本书可以鼓励人们思考这样的框架并影响它们的开发。

1.6    模式使用

模式是软件技术上一种新的发展,我们也在发展新的方法来帮助人们在他们的工作中学习这些模式。面对书中大段的模式,很容易有一种被淹没的感觉(或不知所措的感觉)。

首先需要得到一个大致的方向,看完本章的介绍之后,建议你看看每一章的介绍,从那些介绍中可以了解到章节覆盖的主题。这时你就可以继续并阅读每一个章节了,当然这本书的写作方式并不要求你仔细读完每个章节。如果你在一个特定的领域工作,就可以阅读你认为合适的一些章节。另一种人们建议的方式是浏览书中的图表,如果发现感兴趣的地方,再看看样例,你可以从样例中看出该模式是否会对你有用。模式表也提供了模式的一个小结,可以从它开始或以后用来巩固记忆。

一旦你确定一个可能有用的模式,试一试。我发现要真正理解一个模式如何工作最好的办法就是自己找一个问题进行实验。可以只是在纸上划一个特定的模型,或写些代码看看。要尽量使模式合适(对问题),但也不要花费太大精力,因为可能这个模式并不是最合适的,那样的话没有浪费你的时间,因为你已经学到了关于模型的一些知识,可能还有关于问题的一些知识。如果模式确实不符合你的要求,尽管修改它。模式只是建议,而不是规定。不管有多适合,请详细阅读关于模式的所有说明,以确认你已经了解该模式的局限性和重要的特点。使用之前和使用之后都请别忘了这么做。如果你发现模式中一些没有给出说明的地方,不要只是骂我——发个邮件让我知道(100031.3311@compuserve.com),我非常希望能够看到别人怎样使用这些模式。

当在项目中使用模式时,我必须了解客户的意见。有些客户不喜欢自己和其他任何客户相似,他们自认为与众不同,并且怀疑外来的思想。对这些客户我不展示模式。在某个模式可能适合的地方,我用它来帮我设计问题,用这些问题引导客户走向这个模式,但我不是直接这么做,而是用问题来刺激他们。

另外一些客户高兴看到我公开使用模式,并放心让我重用以前的工作。对这些客户我在他们面前实验模式,并询问他们看他们是否喜欢。对我来说,他们必须明白,我并非把模式看作福音书,而且如果他们觉得不好,我会试试别的(模式)。因为这类客户可能存在不假思索地接受这些模式的危险。

对于回顾你自己或其他人的工作,模式也是非常重要的。对于你自己的工作,看看是否有和模式相近的,如果有,用模式试试看。即使你相信自己的解决方案更好,也要使用模式并找出你的方案为什么更适合的原因。我发现这样可以更好地理解问题。对于其他人的工作也同样如此。如果你找到一个相近的模式,把它当作一个起点来向你正在回顾的工作发问:它和模式相比强在哪里?模式是否包含该工作中没有的东西?如果有,重要吗?我把正在回顾的工作中的模型和我知道的模式相比较,经常发现在这个过程中,当我问自己“它为什么这样处理?”的时候,学到了很多关于模式和关于问题的东西。简单地问问为什么就能学到那么多东西,真让人惊奇。

写一本书经常意味着一定的权威性,读者容易把书当作肯定性的声明。尽管一些作者觉得他们说的相当正确,我却不这样认为。这些模型都来自实践,而且最多我能肯定它们对你有用。然而,我比其他任何人都更痛苦地知道它们的局限性在哪里。要得到真正的权威性,这些模型必须被大量的应用验证,不只是我的实践经验。

这并不表明这些模式没有用,它们代表了大量谨慎的思考。就象它们在我的建模工作中给我一个主要的起点,我希望它们也能对你有所帮助。重要的是,它们是一个起点,而不是一个终点。花些时间理解它们如何工作,但也要去了解如何开发它们和它们的局限性。不要害怕继续向前,并请努力产生更新的更好的思想。同客户一起工作时,我并不把模式看成教条,哪怕是我自己创造的模式。每个项目的需求都会让我采用、改进和提高这些模式。

建模原则 Patterns are a starting point, not a destination.

建模原则 Models are not right or wrong, they are more or less useful.