构架是涉众进行交流的手段 软件系统的涉众--客户、用户、项目经理、程序员、测试人员等--分别关注系统的不同特征,而这些特征都受构架影响。例如,用户关心的是系统的可靠性和可用性;客户关心的是构架能否在规定时间内实现,并且开支不超出预算;项目经理关心的是如果按此构架进行开发,能否保证各小组的任务在很大程度上都独立完成,各部分的交互方式是否规范、可控;而设计师所关心的则是实现构架的所有这些目标的策略。
构架提供了一种共同语言,有关各方可借助它表达和协商各自的需求,并理性地找到解决方案,即使对大型、复杂系统的开发也是如此。如果没有这样一种语言,要想充分理解大型系统并理智地做出对系统质量和易用性都具有重要影响的早期决策将十分困难。构架分析不仅依赖于而且促进了这个层次上的交流。
构架是早期设计决策的体现 构架明确了对系统实现的约束条件。如果系统实现遵循构架设计中所做出的关于系统结构的决策,则系统实现将能够体现出构架的特色。
资源分配方面的决策也制约着系统实现。这些决策对从事各元素开发的实现人员来说可能是不可见的。这些限制条件使将各方关心的问题分离开成为可能,从而使管理者能够做出科学的决策,最大限度地利用人才和计算资源。各元素的开发者对自己所从事的开发任务的要求必须十分清楚,但没有必要了解在构架上所做的权衡。相反,构架设计师未必要精通算法设计或编程语言的各个方面,但必须能够做出构架上的合理权衡。
构架决定了开发组织的组织结构。因为系统的构架中包含了对系统的最高层次的分解,因而一般被作为工作分解结构的基础;这反过来也规定了计划、调度及预算的单元,组内交流的渠道,配置控制和文件系统的组织,集成与测试计划和规程,甚至提出了对一些琐事的要求。各开发小组根据构架中各主要元素的接口规范进行交流。一旦进入维护阶段,维护活动也会反映出软件的结构,常由不同的小组分别负责各具体部分的维护。
建立工作分解结构的一个副作用:它限定了软件构架的某些方面。如果已经将某个子系统的开发交由某个小组完成,则该小组会对将此任务分派给其他小组提出异议。如果这种责任划分已经用合同的形式确定下来,则改变任务分配的代价可能是昂贵的。对分配到各小组的任务的进展情况的跟踪也要困难得多。
因此,一旦对构架达成一致,不管是由于管理上的还是商业伤的原因,想要对它进行修改,几乎都是不可能的。这也是为什么在确定某个大型系统的构架之前必须进行全面分析的原因之一。
构架阻止或支持系统的质量属性的实现。 系统能否具有所期望的质量属性主要是由其构架决定的。第5章将详细讨论构架和质量属性之间的关系,现在仅需牢记以下几点:
- 如果您的系统要求高性能,就需要管理元素基于时间的行为以及元素间通信的频率和数量。
- 如果可修改性很重要,就需要给元素分配责任,以使对系统的修改不会产生很大的影响。
- 如果系统必须非常安全,就需要管理和保护元素间的通信以及允许哪些元素访问哪些信息。可能还需要在构架中引入专门的元素(如受信的内核)
- 如果您认为系统需要可扩展性,就必须仔细定位资源的使用,以有利于引入容量更高的更换组件。
- 如果项目需要交付系统的增量式子集,就必须仔细管理组件间的使用。
- 如果希望可以在其他系统中重要该系统的元素,就需要限制元素间的耦合,以便提取元素时,它能发挥作用,且不会与当前环境有过多依赖。
这些和其他质量属性策略都与构架有很大关系。然而,仅靠构架也无法保证系统功能和质量属性的实现,理解这一点非常重要。
通过研究构架来预测系统质量。能否在系统开发和部署前就知道做出了适当的构架决策(也就是系统是否将表现出所期望的质量属性)? 所幸的是,仅仅依靠对构架的评估来预测系统未来的质量属性是可能的。
构架使推理判断和控制更改更简单。每个构架都将可能的更改划分为3类:本地的、非本地的和构架上的。本地更改只需修改某一个元素就可以实现。非本地更改的实现则需对多个元素进行修改,但并不改动构架。构架的更改会影响各元素之间交互的基本方式--即构架模式--并很可能要求系统做全面的修改。显然,仅做本地更改是最理想的。所以,一个富有生命力的构架应该是这样的:最有可能发生的更改也是最容易进行的更改。 构架有助于循序渐进的原型设计。一旦确定了构架,就可以对其进行分析,并将其原型构造为一个骨架系统。这从两个方面协助开发过程的顺利进行:
- 在产品生命期的早期就能得到一个可执行的系统。随着原型中的各部分逐渐被真实系统各部分的最终实现所代替,原型的这种真实性将越来越明显地体现出来。原型的各组成部分可能与系统的最终实现有较大差异,也可能能够比较逼真地处理和产生数据。
- 使系统在早期执行的一个特例就是在产品生命期的早期确定潜在的性能问题。
可以通过构架进行更准确的成本和进度估计。 成本和进度估计是一个重要的管理工具,它能够使管理人员获得必要的资源并了解项目开发中是否遇到了困难。与了解整个系统相比,了解系统的某些部分本质上可以使成本估计更加准确。正如我们已经说过的,项目的组织结构基于它的构架。与项目经理相比,每个小组能够对其所开发的部分进行更准确的估计,并且在使估计成为现实的过程中,拥有强烈的主人翁责任感。第二,构架的最初定义意味着已经评审了系统的需求,从某种意义上来说,已经对需求进行了验证。对系统范围了解的越多,估计就会越准确。
构架是可传递、可重用的模型 在整个生命期中,重要的越早,收益就越大。代码的重用能带来极大的便利,而在构架层次上的重用则为具有类似需求的系统开发提供了有利的手段。不仅可以实现代码的重用,还可以实现决定构架选用的系统需求及构建构架的经验的重用。如果构架决策能够在多个系统中得到重用,则也可以获得上面讲到的早期决策所带来的所有好处。 产品线共享一个公共的构架。 软件产品线或家族是一组软件密集型系统,这些系统共享一个公共的、可管理性的特性集,满足了待定市场或任务的具体需要,是 按照规定的方式根据一组公共的核心资产开发的。在这些核心资产中,主要部分就是设计用来处理整个家族需要的构架。产品线设计师通过制定在早期适用与整个家族的设计决策,以及在后期仅适用于单个成员的其他决策,来选择一个满足产品线的所有预想成员的构架。该构架定义了对产品线的所有成员来说,什么是固定的,什么是可变的。对多系统开发来说,软件产品线是一种强大的开发方法,它可以在上市时间、成本、生产率和产品质量方面实现极大的回报。构架的强大源于范例的核心。与其他资本投资类似,产品线的构架将成为开发组织的核心资产。 系统开发可以使用大型的、由其他组织开发的元素。以前的软件范例总是将编程作为最根本的任务,把编写了多少行代码作为衡量项目进展情况的依据。基于构架的开发则更强调对各元素的组合或装配,而这些元素很可能已分别甚至是完全独立地开发实现了。由于构架定义了可以集成到系统中的元素,因此,这种组合是可能的。构架从元素与环境的交互、对控制的接收和释放、所能使用或产生的数据、访问数据的方式、通信方式以及用于通信和资源共享的协议等方面对可能做的更换做了种种约定。 元素结构、接口和操作概念的组织是构架的一个重要方面。互换性是这种组织的最重要的原则。 商业组件、子系统、兼容的通信接口都是基于互换性原则的。 少就是多:限制选择范围是值得的。随着所积累的构架模式和设计模式越来越多,我们将会越来越清楚地认识到:虽然计算机程序可以以近乎无限的方式来组合,但涉及到程序的协调和交互时,有意识地限制在一定范围内选择将使我们受益匪浅。也就是说,我们希望使所构建系统的设计尽可能简单。这种方法的优势包括:重用程度更高、更易于理解和交流的简单规范的设计、更为透彻的分析、更短的选择时间、更强的可互操作性。 软件设计的特性来自于构架模式的选择。那些更适用于某个特定问题的构架模式将改善设计方案的实现,这可能通过更轻松地在相冲突的设计要求之间进行权衡、提高对设计环境的人认识和/或使需求描述中的不一致性更为突出等方式体现出来。 系统构架与软件构架。在过去的5到10年中,我们在很多场合对软件构架进行了讨论。每次总会有人提出如下问题:为什么谈论软件构架?系统构架是否同软件构架一样重要?或者说软件构架和系统构架之间的区别是什么? 在创建软件构架时,通常很少考虑系统。 如果您想让构架具有很高的性能,就需要了解该系统将运行的硬件平台的物理特性以及该系统将与之交互的任何设备的特性,您通常还会关注网络的特性。如果您需要构架具有很高的可靠性,也需要关注硬件,在这种情况下就是关心其故障率和冗余处理或网络设备的可用性。如此等等,不一而足。设计师很少考虑硬件。 因此,设计软件构架时,大概需要考虑整个系统--硬件和软件,否则就是蛮干。当仅规定了系统的一部分时,任何一个工程师都不可能预测系统的特性。 但我们主要谈论的仍然是软件构架而非系统构架。这是为什么呢?因为大多数设计师在软件方面都可以做出选择,而在硬件方面则没有这种自由。 构架使基于模板的开发成为可能。构架体现了关于元素交互方式的设计决策。这些决策虽然是每个元素的实现中体现出来的,但却能够局部化,只需编写一次即可。可以在某处用模板将元素间的交互机制描述清楚。 构架可以做为培训的基础。 在对项目新成员介绍所开发的系统时间,可以首先介绍系统的结构,以及对组件之间如何交互从而实现系统需求的高层次的描述。我们曾经指出,软件构架的重要用途之一就是支持并促进各涉众之间的交流,这进一步印证了我们的观点。构架是一个公共的参考点。