答案: 第2章 组织模式
版本: 1.1.0
“于是,每种模式既依赖于它所包含的更小的模式,又依赖于包含它的更大的模式。”— Christopher Alexander 发表于The Timeless Way of Building
一项技术领域的革新通常会易做图另一个领域的突破。雷达技术促进了微波炉这一烹调设备的诞生。Internet 本身最初被设计为一种具有预防单点攻击能力的军事通信网络,而现在已转变为世界上最大的知识储存库。同样,模式最初应用于建筑和城镇体系结构,但很快就被软件开发社区采用,并作为一种描述复杂软件系统的方法。
现在,每天都在涌现出大量与软件相关的模式。大量模式引发了一系列新的挑战。开发人员如何标识那些与手头的任务最相关的模式?模式集合是否足以描述整个解决方案?
本章通过示范如何完成下列任务而回答了其中的一些问题:
标识模式之间的关系。
将模式组合成群集。
标识位于不同抽象级别的模式。
将模式应用于一个解决方案的多个方面。
将模式组织为框架。
使用模式来简述解决方案。
模式的模式
面向对象的编程社区之所以如此重视模式,是由于模式能够描述关系。面向对象编程的基本元素是类。但是,如果抛开与构成解决方案的其他类的关系不谈,单个类就没有太大意义。每种模式通常都描述一组类,并强调它们之间的关系和交互。因此,模式将大量类转换成更易于管理的模式集合。
由于在一般应用程序中,可用模式的数量很容易超出类的数量,因此您可能突然发现自己位于模式的海洋。那么,怎样才能了解所有这些模式的含义呢?重申一遍,项目之间的关系似乎是问题的关键。显而易见,一些模式与其他模式紧密相关。例如,有些模式是对另一些模式的优化。Three-Tiered Distribution (易做图分布)是Tiered Distribution(分级分布)概念的一个具体应用。Observer (观察器)通常用于实现 Model-View-Controller (模型-视图-控制器)模式的一部分。Page Controller (页面控制器)更加详细地描述了 Model-View-Controller 的控制器部分。在 ASP.NET 中实现 Page Controller 是使用 Microsoft® ASP.NET 对 Page Controller 模式的实现。
要开始按照关系组织模式,请将一组模式设想成小圆(请参阅图 1):
图 1. 一组模式
如果您在每对具有某种关系的模式之间绘制一条直线,则可以看到如下所示的图片:
图 2. 用直线表示的模式关系
带点随机性的小圆的集合形成了连在一起的模式网。当您查看某种模式时,可以立即标识出与其紧密相关的模式并进行审阅。您还可以标识紧密相关的模式的“邻居”,并查看它们与其他更远的模式存在什么样的关系。
模式群集
使用图表来表示模式之间的关系有助于从一种模式转移到一组相关的模式。但是,它仍不能告诉您该从何处着手。如果您正在构建一个 Web 应用程序,应该首先学习Model-View-Controller 模式,还是应该先查看 Page Cache (页面缓存)?是否还应该查看Broker (代理程序)?
模式群集是一组涉及特定主题区域的模式。例如,您可以从 Web 表示群集开始查找与创建 Web 应用程序前端相关的模式。同样,分布式系统群集包含有助于与远程对象通信的模式。如果将模式集合划分为群集,则可以同时检查一组模式。虽然模式图也显示出了两种模式是相关的,但群集汇总能够更详细地描述如何通过组合不同的模式来构建实际的解决方案。每个群集都为读者提供了指导教程,便于其了解该群集中的所有模式。受 Christopher Alexander 的城镇与构造建筑物世界的启发,您可以将群集与城市邻近地区进行类比。为了将这种类比关系向前推进一点,可以将群集汇总视为当地旅游局提供的交通旅游图。
图 3. 模式群集
最初发布的“使用 Microsoft .NET 的企业解决方案模式 (ESP)”标识出了表 1 中所示的五个群集。
表 1:企业解决方案模式群集
群集 问题
Web 表示 如何创建动态 Web 应用程序?
部署 如何将应用程序划分为层,然后将它们部署到多级硬件基础结构上?
分布式系统 如何与驻留在不同进程或不同计算机中的对象进行通信?
性能和可靠性 如何创建一个能够满足至关重要的操作要求的系统基础结构?
服务 如何访问由其他应用程序提供的服务?如何将您的应用程序功能作为服务呈现给其他应用程序?
第 3 章到第 7 章将详述这些群集。
不同的抽象级别
将模式划分成群集可使其更便于管理。如果您要构建 Web 应用程序的前端,请从 Web 表示群集着手,然后参加快速教程并查看有哪些其他模式与该群集相关。但请牢记一点,不同的人可能对构建 Web 应用程序的不同方面感兴趣,这取决于他们所扮演的角色或项目所处的阶段。开发人员可能对在 Microsoft .NET Framework 上以最高的效率实现Page Controller 模式最感兴趣,而体系结构设计者可能对决定是使用易做图还是四级应用程序体系结构更感兴趣。
因此,抽象级别最适合对模式进行分类,以便不同的用户组可以查找与其感兴趣的领域最匹配的模式。从一般到更具体来划分模式有助于确定应当首先考虑哪些模式。在考虑使用 ASP.NET 实现 Page Cache 模式中描述的复杂的 ASP.NET 缓存指令之前,您可能应该先考虑应用程序应该有多少级。
对模式进行分类的方法之一就是将模式图分成如图 4 所示的三个级别。
图 4. 抽象级别
这种划分方法与某些讲述软件模式的最具影响力的图书中使用的术语基本一致。
体系结构模式
“体系结构模式表示软件系统的基础结构组织架构。它提供一组预定义的子系统、指定它们的职责并包括用来组织它们之间关系的规则和准则。”[Buschmann96]
ESP 遵循 Buschmann 等对结构模式的定义。这些模式描述如何在最高级别构造应用程序。例如,Layered Application (分层应用程序)模式就是一种体系结构模式。
设计模式
“设计模式提供一种用来优化软件系统的子系统或组件或者相互之间的关系的架构。它描述通信组件中经常重复使用的、能够解决特定上下文中的一般设计问题的结构。” [Gamma95]
设计模式提供下一级别的优化,如 Gamma 等的创作性作品中所述。许多图标性模式(如 Model-View-Controller 或Singleton)都位于这一层。
实现模式
模式社区将更详细的、特定于编程语言的模式称为惯用语。此定义适合于软件模式。但是,本指南的适用范围并不局限于软件,它同样适用于软件密集型系统,包括将软件部署到硬件处理节点以提供整体的业务解决方案。因此,ESP 对 Pattern-Oriented Software Architecture (POSA) [Buschmann96] 中给出的惯用语的定义进行了修改,以反映更广泛的范围并将这些模式重新标记为实现模式:
实现模式是特定于某个特殊平台的更低一级的模式。实现模式描述如何使用给定平台的功能实现组件的某些方面或它们之间的关系。
ESP 实现模式阐明了如何使用 .NET Framework 实现设计概念。在某些情况下,该框架中已经包含了大量工作,这更便于开发人员执行任务。
--------------------------------------------------------------------------------
注意:虽然 POSA [Buschmann96] 将惯用语定义为了模式,而且 The Timeless Way of Building [Alexander79] 在 Alexander 的原始模式作品中包括实现模式,但在模式社区的一些成员之间,仍就实现模式是否为真正的模式存在争议。无论如何对它们进行分类,在考虑模式时它们都非常有用,因此将其包含在了本指南中。
--------------------------------------------------------------------------------
如果将模式集合划分为三个抽象级别,则更便于不同的用户组标识与其感兴趣且擅长的领域相关的模式。生成的模型从高级别组织流出,途经对子系统和组件进行的不断优化,最后使用平台特定的技术实现了这些模式。
视点
虽然抽象级别有助于解决不同用户组的问题,但是它们不能反映出软件解决方案比代码组件包含更多内容这一事实。构建企业解决方案的整体视图包括自定义开发的软件、平台软件、硬件基础结构以及软件到硬件的部署。由于这些区域互相之间存在非常明显的区别,所以有必要将这些模式与该命名相对应。
请牢记,这四个区域描述的是同一个解决方案的不同视点。因此,与优化级别不同的是,这些视点不描述层次结构,而只是提供看待同一事情的四种不同方法。您可以将这些视点比喻为不同类型的地图。一个地区的某张地图可能描绘的是交通网(如公路和高速公路),而同一地区的另一张地图显示的是地形。还可能有另一张地图用来显示州界和县界。每张地图都有其各自的词汇。例如,地形图中的直线表示海拔,而交通图中的直线表示街道。然而,所有地图描述的都是同一个主题:特定的地理区域。
每个视点本身还可以强调不同的抽象级别。因此,ESP 将下列视点描绘为模式图中的垂直薄片:数据库、应用程序和基础结构。应用程序视点和基础结构视点之间通常有一个很大的间隙。概念、抽象和技能集都存在足够大的区别,这样可以保证在应用程序视点和基础结构视点之间插入一个缓冲区,以便帮助在二者之间建立连接。此视点被称作部署视点。
此推理过程将产生如表 2 所示的四个视点。
表 2:企业解决方案模式视点
视点 描述
数据库 数据库视图描述应用程序的永久层。此视图包括诸如逻辑和物理架构、数据库表、关系和事务处理等内容。
应用程序 应用程序视图强调解决方案的可执行方面。它包括诸如域模型、类图表、程序集和进程等内容。
部署 部署视图将应用程序关注点明确映射到基础结构关注点(如将进程映射到处理器)。
基础结构 基础结构视图包含运行解决方案所必需的所有硬件和网络设备。
图5 将这些视点以竖线形式覆盖到模式图和抽象级别上。
图 5. 添加视点
为简单起见,图 5 未显示群集的边界。但是,群集、抽象级别和视点是平行存在的。它们代表访问同一组模式的不同方法。
模式框架
垂直轴上的三个优化级别以及水平轴上的四个视点这一组合形成一个网格状的模式组织图。图 6 显示了这种名为模式框架的排列。
图 6. 模式框架
模式框架作为参考点和导航助手随每个单独的模式描述提供。
约束
模式框架按照各种有意义的子类别组织模式集合。例如,现在可以将重点放在数据库视图的设计模式或应用程序视图的实现模式。
但是,软件采用了各种各样的形式。目前,软件运行在以下几类系统上:嵌入式系统(如起搏器和电信设备)、实时系统(如防锁死刹车系统)或数据仓库系统(旨在分析消费者的购买行为)。如果尝试处理与各种形式的所有软件解决方案相关的模式,将快速扩展任何单一的图书或模式储存库的作用范围。因此,ESP 将模式限制在企业业务解决方案上。因为 ESP 这一术语有些模糊,所以它只是标识模式图中一小组特定的顶级体系结构模式或根模式。该集合中的所有其他模式都遵循下列约束:
联机事务处理 (OLTP)
面向对象
分层应用程序
分级分布系统
OLTP 系统是用来管理事务处理的数据库子系统。这些子系统确保每个事务的原子性、一致性、独立性及持久性(所谓的 ACID 特性)。实际上,这些应用程序通常处理一个或多个用来维护企业业务状态的关系数据库。换句话说,这些应用程序是用来跟踪客户、订单、帐户等的数据库。通过将 OLTP 标识为模式框架中的顶级约束,ESP 排除了不支持事务处理的联机分析处理 (OLAP) 系统或简易做图面文件系统。OLTP 的“联机”特性意味着一旦业务状态发生变化,这些系统将立即读取或更新数据库,而不考虑脱机批处理。
从应用程序视点考虑,模式框架受两种模式的约束:Object-Oriented Application(面向对象的应用程序)和Layered Application.(分层应用程序)。大多数(如果不是全部)应用程序视点模式都依赖面向对象的概念(如封装、多形性和继承)来成功解决影响它们的问题。因此,模式框架只处理面向对象的应用程序,并不特意处理程序上的应用程序。
引人注目的企业应用程序通常包括大量对象和服务,这些对象和服务必须通过协作来提供对业务存在一定价值的东西。为了管理这些协作,必须存在某个高级别系统组织。大多数企业级系统都使用分层方法来管理这种复杂性。因此,模式框架只处理设计为一系列层的应用程序,并特意排除没有或者具有较少内部结构的单一应用程序。
从基础结构视点,该模型被限制在支持跨多个按级排列的服务器分布应用程序的硬件基础结构上。这种分级方法通常用于企业应用程序,这是由于它的启动成本相对较低,而且它支持扩展策略(可通过向基础结构中添加开销不大的服务器以递增方式增加容量)。从模型中排除的是基于以下操作的解决方案:将应用程序部署到单个主机或大型多处理器计算机中。
部署视点关注以下问题:缝合应用程序视点和基础结构视点之间的间隙。因此,它本身没有任何约束,但运行时受应用程序视点和基础结构视点所设置的约束的限制。换句话说,最高级别的部署模式涉及的是将分层应用程序映射到分级分布基础结构中,而不对它本身施加任何其他约束。
如果将这四个高级别约束或根约束视为一个组,将有助于缩小在本指南其余部分中讨论的模式的范围。图 7 显示了位于模块框架顶部的根约束。
图 7. 模式框架的根约束
通过缩小模式框架的范围,可以更详细地阐述具体模式以及这些模式之间的关系。
Pattlets
使用根约束可以将模式的数量减少到易于管理的数量级。然而,详述该网格中的所有模式可能需要大量的工作。如果分开开发所有模式,然后发布“最终模式指南”,将无法获得许多由模式社区实现的价值。随着大家对模式的理解的进步,模式也需要发展。模式不是由单个作者创建的,而是软件开发社区实际应用的结晶。在认识到模式的发展本质之后,本指南的作者已经发布了本文中包括的模式的子集,目的在于听取大家的意见并着手组建一个社区。
但是,如果将模式延缓到稍后一些,会在模式图中留下漏洞,这可能会导致相关的模式突然断开连接。为了使模式图中的关系保持完整,本指南提供了第一版本中未包括的模式(即 Pattlet)。Pattlet 是尚未详细记载的实际模式。Pattlet 描述问题的解决方案,但是不包含对可能影响解决方案的上下文、问题或因素的详细说明。
Pattlet 这一概念对于参考以前的模式作品也非常有用。在过去的十年中,模式社区一直发现并记录软件模式。如果试图重复这些工作,将是非常愚蠢的。而要求读者购买几本其他图书来了解这些模式的上下文的想法也很不明智。因此,本指南在参考有关模式的现有图书中所描述的模式时,包括了一个 Pattlet 模式。Pattlet 还包括对原始作品的参考,以供那些希望更详细查看完整模式的读者参考。
有关所有 Pattlet 的详细列表,请参阅附录 A。
解决方案的模式语言
受到约束的模式框架及其所包含的模式提供了足够多的数据点,以便开始使用模式来描述整个解决方案。实际上,第 1 章中的报价示例可以用模式术语来描述。回忆一下,其要求中指定了一个基于 Web 的报价应用程序。描述解决方案体系结构的用户可能会做如下表述:
首先让我们在抽象的体系结构级别看一下这个报价应用程序。从应用程序视点,报价应用程序是面向对象的应用程序,它在逻辑上构造成Three-Layered Services Application. (三层服务应用程序)。从数据库视点,应用程序是基于 OLTP 处理模型的。从基础结构视点,硬件和网络体系结构是基于 Four-Tiered Distribution(四级分布)的,这要求 Web 服务器功能和应用程序服务器功能具有不同的物理级。最后,从部署视点,小组已经基于复杂的 Web 应用程序创建了一个Deployment Plan (部署规划),以便将组件映射到服务器。
这从所有这四个视点向熟悉参考模式的读者简述了解决方案的体系结构。继续向下移动一个抽象级别,可能会看到作者这样描述系统设计:
从应用程序视点,让我们分别考虑 Three-Layered Services Application(三层服务应用程序)的每一层。
表示层是围绕基于Model-View-Controller (MVC) 的 Web 表示框架构造的。尽管 MVC 将业务层和表示逻辑层分开了,但是每一页都包含大量公共逻辑。为了消除这种冗余,我们使用Page Controller 来呈现公共头和尾注信息并为用户设置友好的显示名称。
业务层包含客户、报价、订单、系列物品和库存域对象。由于开发速度是一个重要要求,因此这些域对象是使用 Table Module(表模块)[Fowler03] 实现的。复杂的 Web 应用程序 Deployment Model (部署模型)要求 Web 级和应用程序级分开。因此,这两级通过一个代理程序进行通信。业务实体充当 Data Transfer Objects [Fowler03],用于封装在这两级之间传送的信息。
数据层使用 Data Table Gateway [Fowler03] 来访问 OLTP 数据库子系统,并使用大量数据访问组件来支持域对象的持久性要求。
从基础结构视点:为了满足业务的操作要求,我们通过添加Load-Balanced Cluster (负载平衡群集)和Failover Cluster(故障转移群集)来基于基本的 Four-Tiered Distribution(四级分布)模型构建。为了满足高级别并发用户的要求,我们在 Web 级中添加了负载平衡功能。为了满足可用性要求,我们在数据库级中添加了群集。
可以继续描述位于同一抽象级别的数据和部署视点。为此,再向下移动一个抽象级别,可能会看到作者这样描述解决方案的实现:
让我们从应用程序视点来查看解决方案。解决方案是使用 Microsoft .NET 技术构建的。表示层基于 ASP.NET 中内置的 Web 表示框架。ASP.NET 使用内置的代码隐藏页功能来简化 Model-View-Controller 的实现。我们使用 ASP.NET 中内置的 Page Controller 机制来实现表示逻辑。业务层中的域对象是 .NET 托管对象。因为表示层和业务层部署在不同的级上,所以我们使用服务器激活对象通过 .NET Remoting 实现 Broker。最后,数据层基于 .NET Framework 中的 ADO.NET 类来提供数据库访问。Table Modules(表模块)和业务实体是使用 ADO.NET 的数据集组件构造的。数据访问组件的其余部分由 Microsoft Application Blocks for .NET 构建块提供。
从基础结构视点:Microsoft SQL Server® 运行在故障转移群集中,用于 OLTP 数据库子系统中。Microsoft 网络负载平衡群集在 Web 服务器之间提供负载平衡。
所有这些会话都经常参考各种模式。最初,这可能有点让人望而却步,但当您了解所使用的模式后,就会认识到即使是一个简短的描述也会让您详细了解系统是如何工作的。请注意,您不必翻阅大量文档或逐步执行无穷无尽的代码行,即可对此有所了解。设想一下在不使用模式的情况下描述解决方案而需涉及到的工作,就不难知道模式所带来的沟通好处。
小结
本章阐释了模式如何在不影响细节的情况下提供可以高效描述复杂解决方案的词汇。模式有效地构成了一种新语言,体系结构设计者和设计人员可以使用它们来交流其想法。
由于在构建企业解决方案时会涉及到大量模式,所以学习这个新语言似乎很难。本指南将各种模式组织成了更小、更紧密相关的模式集,这使您能够根据自己的具体兴趣或项目的阶段,从使用一小组模式开始。
本章介绍了四个有助于浏览模式的机制:
关系。模式之间的关系有助于标识与所用模式紧密相关的模式(如 Page Controller 强调 Model-View-Controller 的控制器方面)。
群集。群集将属于共同主题范围的模式组合在一起(如 Web 表示)。
抽象级别。抽象级别使您能够以一种与讨论的详细程度相一致的方式来描述概念(如体系结构会话)。
视点。视点有助于选择与小组的特定角色相关的词汇(如基础结构小组)。
这些机制并不是要约束您的想法,而是旨在方便您查看复杂系统。实际上,当您在角色、主题范围和详细程度之间切换时,您也将自然而然地在这些机制之间进行了切换。
上一个:使用 Microsoft .NET 的企业解决方案模式(4)
下一个:使用 Microsoft .NET 的企业解决方案模式(2)