软件架构实践 V2:第一章

发布时间 2024-01-07 00:07:37作者: LHX2018

第一部分 预想架构

第一章 架构商业周期

作为设计过程的重要组成部分,现在已经提出了构架的概念。构架是本书的主题。“软件构架”包含大型软件系统的结构。系统的构架视图是抽象的,它不考虑实现、算法和数据表示的细节,集中研究“黑盒”元素的行为和交互。在设计具有所期望属性的系统时,开发软件架构是第一步。

定义:程序或计算系统的软件构架是该系统的一个(或多个)结构,它由软件元素、元素的外部可见属性以及它们之间的关系组成。

案例:瑞典瓦萨战舰完工即沉没

人们对该舰的沉没提出了各种各样的质疑,最后的结论是:该舰制造工艺精良,但“比例严重失调"”。

系统需求来自于企业目标,构架来自于系统需求,系统来自于构架。构架与设计师的经验、当时的技术水平有着密切的联系。可怜的 Hybertsson 在设计瓦萨战舰时,无论从他本人的经验还是从当时的技术水平来看,都不具备相应的条件。

本书将讲述Hybertsson 本应用到的如下3方面的内容:

(1) 能够满足苛刻需求的成功构架案例分析,以确定当前的技术水平

(2)在构建系统之前使用对所用构架进行评估的方法,以减小开发一个无先例的全新系统所承担的风险

(3)基于构架的增量开发技巧,以及时发现设计缺陷并加以改进

我们关注的焦点问题是:系统的软件构架与构建系统时的环境及系统未来所处的环境有什么关系?此问题的答案就是组织本书内容所遵循的原则。软件构架是技术、商业和社会等诸多因素作用的结果,而软件构架的存在反过来又会影响技术、商业和社会环境,从而影响到未来的构架。我们把这种相互影响的周期一一从环境到构架又返回到环境——称作构架商业周期(Archittecture Businees Cycle,ABC)

本章将详细讲述ABC的概念,并为后续章节的阐述奠定基础。本书详细讨论构架商业周期的如下方面:

  • 组织目标如何影响需求和开发策略
  • 如何从需求得出架构
  • 如何对架构进行分析
  • 架构如何产生体现新的组织能力和需求的系统

1.1 架构的产生

在任何一次开发中,系统需求都能够明确反映出对系统最终特性的某些期望。并不是系统需求中的所有内容都和系统最终具备的特性直接相关。开发过程或某个工具的选用可能会受到系统需求的制约,但对系统需求的表述仅仅是万里长征第一步。如果不能满足除系统需求之外的其他一些要求,所开发出来的系统很可能就像不能正常运行的系统一样一文不值。

我们通过确定与架构有关的影响因素开始构建ABC。

1)架构受系统涉众的影响

很多人和组织都对构建软件系统感兴趣。我们把这样的人或组织称为涉众:客户、最终用户、开发人员、项目经理、维护人员以及那些对系统进行市场营销活动的人等等。这些涉众所关注的问题各不相同,但都要系统能够在他们所关注的方面提供保障或优化。

一个得到各方认可的系统需要在以下方面达到相应要求:性能、可靠性、可用性、平性能、平台兼容性、内存的利用、网络使用程度、安全性、可修改性、易用性,与其他系统的互操作性以及行为

当然,最基本的问题是,每个涉众所关心的问题和期望各不相同,而且有些是相互矛盾的。但是,很少有需求文档能够以一种可测试的细节捕获系统所有的质量需求。

2)架构受开发组织的影响

人员的技能也是一个影响因素,开发进度和预算也会对架构产生营销。

开发组织对软件架构的影响可以分为3类,即直接影响、长远影响和组织结构的影响。

  • 开发组织可能会对某些资产进行直接商业投资,如现有的构架和基于这些构架的产品。开发项目的基础可能是所要开发的新系统是已有类似产品线的延续,其开发成本中有很大一部分属于资产重用。
  • 开发组织可能希望对某个基础结构进行长期的商业投资以实现某项战略目标,并且可能会把开发的系统视作为此基础结构融资或进一步扩展此基础结构的手段
  • 开发组织本身的结构也会影响架构的形成(康威定律)

3)架构受设计师的素质和经验的影响

设计构架时所做的各种选择与设计师本人所受的教育或培训背景、对其他成功构架的了解以及对某些性能极佳或极差的系统的了解有关。设计构架时,设计师可能想实践一下某种构架模式,或者是尝试使用在某本书(例如本书)上或某门课程中所学到的技巧

4)架构受技术环境的影响

技术环境看作是对设计师素质和经验的特殊反映

5)影响架构的其他因素

影响构架的因素有很多。一些只是隐含的,还有一些则很明显是冲突的

软件开发者几乎从来没有真正理解过企业目标所要求的系统性能,更不必说完全实现了。确实,连客户的需求都很少完全编成文档,这意味着还没有解决不同涉众目标之间不可避免的冲突。

然而,设计师需要尽早知道并理解特性、源以及对项目的限制的优先级。因此,设计师必须确定出各类涉众,并积极促使他们表达出对系统的需求或期望。如果不做这样的工作,在设计展开后,就会出现某些涉众要求设计师解释为什么不采用所提出的其他方案的情况,这显然会项目的开发进度,降低工作效率。

要设计出好的构架,设计师仅具有高超的专业技术是不够的,这个道理显而易见。设计师需要不断地向涉众解释针对不同属性所做的各种取舍,以及为何无法满足涉众的所有要求。因此,成功的设计师还必须具备与人交往、谈判和交流的技巧。

image
6)架构对诸影响因素的反作用

本书的主旨就是要阐明企业目标、产品需求、设计师的经验、构架和最终系统之间的关系一它们构成带有反馈回路的、可由开发组织实施管理的周期。开发组织对这个周期管理得好,就能够不断成长壮大,拓展其经营范围,充分利用以前在构架和系统构建方面的投资。
image
下面我们就来看一下该周期是如何运作的:

1)架构影响着开发组织的结构。架构规定了系统的结构

2)架构会影响开发组织的目标。成功地开发出一个系统,可以使开发公司在相应的市场上占有一席之地。该系统的架构又可以为类似系统的有效生产和部署提供良好的机会,组织可以调整其目标,以利用其新发现的技术来扩宽市场。这就是从改系统到开发组织以及它所构建的系统的反馈

3)架构可能会影响客户对下一个系统的要求。这是因为与完全重新开始设计相比,利用已有的架构可使客户更为及时地获得更可靠、更经济的系统。从经济角度考虑,客户可能会愿意放弃某些性能需求。产品线对那些不能确切表述自己在各种情况下的需求的用户也产生了类似的影响。第15章中,我们将会了解到产品线的构架如何影响客户,从而使之愉快地同意改变自己对系统的需求。这主要是因为通过这种方式,客户可以在很短的时间内拿到既能满足其基本需求,又具有很高可靠性且价格相对低廉的高质量软件系统

4)构建系统的过程丰富了整个开发团体的经验,从而将影响设计师对后继系统的设计

5)一些典型的系统会影响并实际改变软件工程的发展,也就是系统开发人员学习和实践的技术环境

1.2 软件过程和架构商业周期

我们把对软件开发活动的组织、规范和管理成为软件过程。在创建软件架构,使用该架构实现设计,然后实现或管理目标系统或应用软件的演变的过程中,涉及到哪些活动?这些活动包括:

  • 为系统构建一个商业案例
  • 理解系统需求
  • 创建或选择架构
  • 将架构编成文档,并与有关各方进行交流
  • 对此架构进行分析和评价
  • 根据此架构实现系统
  • 保障系统实现符合架构的要求

架构活动

  • 为系统创建商业案例(创建商业案例的含义要比简单地评估某个系统的市场需求广泛得多。这是创建并限制任何未来需求的重要一步。该软件系统定价将会是多少?其目标市场是什么?预期于什么时间正式推出?是否需要与其他系统连接的接口?有什么必须要遵从的限制条件?)
  • 理解需求(用例图,状态图,理解已有系统特性,原型)
  • 创建或选择架构(概念完整性是成功设计系统的关键,而只有通过以小组的形式共同设计系统架构才能真正实现概念完整性 <人月神话>)
  • 架构的交流(要使构架真正成为系统设计的砥柱,就必须向与构架有关的所有涉众清楚而准确地表述构架。开发人员必须理解构架对他们的要求,测试人员必须清楚自己所面临的任务,管理层必须明确构架要求做出什么样的规划。为此,构架文档的信息必须丰富确切清楚,要保证具有不同教育背景的相关人员都能理解。)
  • 架构的分析和评价(在任何设计过程中都会有多个候选的设计方案。可以很快就否决一些方案,然后对另外的方案进行仔细分析和权衡,选择出最合适的一个。以一种合理的方式在这些方案中进行选择是设计师最大挑战之一。)
  • 实现基于该架构的系统(保证开发人员在实际开发中忠实于架构所规定的结构,遵守关于各部分之间交互的约定。)
  • 使架构符合原来的表述(要始终保持清醒的头脑,以保障架构符合原来的表述)

1.3 什么样的架构才算好

架构并不是注定是好的或是坏的。各种架构总是能够或多或少地满足某些系统的要求。我们可以对架构进行评估——这也是我们为什么要关心架构的原因之一——但必须要针对某些特定目标的情况下进行这种评估。这也是本书所要表达的观点之一。

但是,在设计架构时必须遵循一些实践准则。当然,忽视某一条准则并不一定意味着所设计的架构将有致命的缺陷,但至少应当把准则当做一个警示,进行相应的研究分析。

我们把从软件开发中所得到的经验分为两大类:关于过程的建议和关于产品(或结构)的建议。

我们所提出的关于过程的建议主要有如下几条:

  • 构架的设计应该由一位设计师来完成,或者由一个在某位设计师领导下的小组来完成。
  • 设计师(或构架小组)应全面掌握系统的功能需求,并且应有一份所设计构架应满足的划分了优先级的质量属性列表(如安全性或可修改性)。
  • 构架的文档应该完备,至少应有一个静态视图和一个动态视图(在第2章讲述),应该采用所有人员认可的文档形式,以保证所有涉众都能很容易地理解这些文档
  • 应该把构架设计方案交由各涉众传阅,应该让各涉众积极参与设计方案的评审。
  • 应该对构架认真进行分析,得出可应用的量化度量指标(如最大吞吐量)。也应该对质量属性进行正式评估,以避免出现发现问题时为时已晚的情况。
  • 构架的设计应有助于增量式实现。为此,可先创建一个粗略的、具备雏形但功能最简单的系统,通过把这个骨架系统逐步细化、扩大来得到所期望的系统。这种做法可简化集成和测试的工作《参见7.4节)。
  • 允许构架带来一定的(少量的)资源争用,但应清楚地给出这些资源争用的解决方案,告之于有关各方,并保证这些解决方案切实可行。例如,若网络占用是要考虑的问题,设计师就要为每个开发小组制定出将网络占用减少到最低限度的指导原则,并保证这些原则得以贯彻。如果系统性能是所考虑的主要问题,设计师就要为各主要线程规定出执行时间的限制,并保证在实现中切实达到该要求。

我们所提出的关于结构的建议主要有如下几条:

  • 构架应采用定义良好的模块,各模块的功能责任划分应基于信息隐藏和相互独立的原则。信息隐藏模块应该包括那些封装了计算基础结构特性的模块,以将大部分软件与计算基础结构的变化隔离开。
  • 应该使用特定于每个属性的众所周知的构架战术来实现质量属性,如第5章(实现质量属性)所述。
  • 构架绝对不可以依赖于某个特定版本的商业产品或工具。如果确实依赖于某个商业产品,则要合理设计构架,使得当所依赖的商业产品发生变化时,能够方便、经济地适应。
  • 应将产生数据的模块和使用数据的模块分离开。未来的变化往往仅限于数据的产生或数据的使用,所以,这样做一般可以提高系统的可修改性。如果系统中需要添加新数据,则这两个部分都要做相应的修改,但如果这两个部分是相互独立的,就可以对系统进行分阶段逐步(增量式)升级
  • 对于并行处理系统,构架应该采用定义良好的进程或任务,它们未必反映模块分解结构。也就是说,有些进程的运行涉及到若干个模块,而模块中的某个过程可能也要为若干个进程所调用 (第3章的A-7E案例分析是采用该原则的一个示例)
  • 每个任务或进程的编写都要考虑到与特定处理器的关系,并保证(甚至在运行时)能够方便地改变这种关系。
  • 构架应该采用少量的、简单的交互模式(参见第5章)。即在整个运行过程中,系统的功能应保持一致。这可使系统易于理解,有助于缩短开发时间、提高可靠性、增强可修改性。它还应该展示构架中的概念完整性一一虽然无法度量,但却有利于系统开发的顺利进行。

1.4 小结(略)

1.5 讨论题(略)