软件架构设计:实用方法及实践
上QQ阅读APP看书,第一时间看更新

2.5 设计概念:用于创建结构的构建块

设计不是随意的,而是有计划的、有目的的、有理性的、有针对性的。设计的过程开始可能是艰巨的。当任何设计活动开始面对“空白页”时,各种可能性的空间也许显得不可思议的巨大而复杂。然而这里有一些帮助。在几十年的过程中,软件架构社区创造并发展了一个能够被普遍接受的设计原则,可以指导我们创建高品质可预见成果的设计。

例如,一些详加记录的设计原则是面向实现具体质量属性的:

❑ 帮助实现高度的可修改性,目标是优秀的模块化,这意味着高内聚、松耦合。

❑ 帮助实现高可用性,避免单点故障。

❑ 帮助实现可扩展性,避免关键资源的硬编码限制。

❑ 帮助实现安全性,限制对关键资源的访问。

❑ 帮助实现可测性,具体化状态。

❑ 等等。

这些原则已经通过在不同情况下的实践中处理这些质量属性发展了几十年。此外,我们已经在设计中并最终在代码中演化了这些抽象方法的可重用的实现。我们将其称为可重用实现的设计概念,它们是构成软件架构的结构的基石。不同类型的设计概念是存在的。在这里,我们会讨论一些最常用的,包括参考架构、部署模式、架构模式、战术和外部开发的组件(如框架)。前四个实际上是概念性的,最后一个是具体的。

2.5.1 参考架构

参考架构是一个蓝图,它为特定类型的应用程序提供一个整体的逻辑结构。参考架构是一个映射到一个或多个架构模式的参考模型。它已在业务和技术环境中被证明是可行的。它通常配备一组简化使用的支持工件。

图2.3中展示了一个用于Web应用程序开发的参考架构示例。这个参考架构创建了这类应用的主层——演示层、业务层和数据层,以及层内的元素类型和这些元素的职责,如UI组件、业务组件、数据访问组件、服务代理等。此外,该参考架构介绍了一些需要加以解决的横向关注点,如安全和通信。正如这个示例所示,当你为应用程序选择一个参考架构时,你同时还引入了一组在设计过程中需要解决的问题。你可能没有一个明确的通信或安全性的需求。但事实上,这些元素是参考架构的一部分,需要你对它们做出设计决策。

图2.3 例子出自微软应用架构指导的网页应用参考体系架构(关键字:UML)

参考架构可能与架构风格相混淆,这两个概念是不同的。架构风格(如“管道和过滤器”和“客户端-服务器”)在一个指定的拓扑结构上定义组件的类型和连接器,对构建一个应用程序无论是在逻辑上或物理上都是非常有用的。这种风格是技术性的并且与领域无关。与此相反,参考架构提供了一个特定领域的应用程序的结构,它们可能会体现不同的风格。此外,虽然架构风格在学术界很受欢迎,但是参考架构似乎是从业者的首选,这也是为什么我们喜欢把它们放在我们的设计概念列表的原因。

虽然有许多参考架构,但我们不知道有哪一个目录包含了大量的参考架构清单。

2.5.2 架构的设计模式

设计模式是概念性的解决方案,它重现了一个已定义内容中存在的设计问题。设计模式起初关注的是对象规模方面的决策,包括实例化、结构化以及行为,然而现有的模式目录在多个粒度层中寻找决策。另外,还有特定的模式去寻找诸如安全或者集成这类的质量属性。

当有人争论着什么是架构模式和更细粒化的设计模式的差异时,我们认为没有原则上的区别,能单纯地归咎在规模量的差异上。当模式直接使用并且充分地影响某些架构驱动因子的满意度时,我们把这个模式认定为架构(参看2.2节)。

图2.4展示了一个架构模式的例子,这个模式有利于结构化系统,叫做分层模式。当选择这样类型的模式时,你必须决定所设计的系统需要多少层。图2.5展示了一个支持并发的模式,有利于提高性能。这个模式也是需要被实例化的——就是说,它需要去适应特定的问题和问题涉及的内容。有关实例化的内容将在第3章中讨论。

图2.4 分层模式,结构化源于面向模式软件架构的应用

虽然参考体系架构可能会被认为是模式的一种类型,但我们更愿意单独地去考虑它们,不仅因为它们在结构化应用中扮演着重要的角色,也因为它们会更直接地连接技术栈。另外,一个参考体系架构通常既包含其他的模式也同时约束着这些模式。例如,图2.3中的网页应用参考体系架构包含了分层模式,但也因此确定了该结构需要使用多少层。参考体系架构还包含了其他的模式,如应用外观模式和数据访问组件模式。

图2.5 半同步/半异步模式,支持来自面向模式的软件架构并发(源自:Softserver)

2.5.3 部署模式

我们想要单独考虑的另外一种模式类型是部署模式。这类模式对于如何在物理上构建系统来部署该系统提供了模型。有一些部署模式,如图2.6有利于根据等级(物理节点),建立一个初始的系统物理结构。更加定制化的部署模式,如图2.7中的负载平衡群集,这些模式是用来满足质量属性(品质特性)的,如有效性、性能和安全。

图2.6 源自微软应用架构指导的四层部署模式(关键字:UML)

图2.7 源于微软应用架构指导,赋予性能的负载平衡的群集部署模式

一般情况下,系统的初始结构要通过对应的逻辑元素来获得,这些元素又是从部署模式所定义的物理元素中的系统架构(和其他的模式)里获得的。

2.5.4 策略

软件架构师能够利用基础设计技术的集合,来实现对特定质量属性的响应。我们称这些架构设计为基本类型策略。策略,就像设计模式一样,是软件架构师已经运用多年的技术。我们不创造策略,而是简单地找到了过去20年以来,软件架构师管理质量属性响应目标时,所实实在在做的那些事。

策略是会影响质量属性响应控制的设计决策。例如,如果想去设计一个低延迟或者高吞吐量的系统,可以制定一组设计决策,充当即将到来的事件(请求服务),产生的反应带有时间约束条件,如图2.8所示。

图2.8 事件和响应间的策略

比起模式,策略更简单、更原始。它们专注在单个质量属性所响应的控制上(当然,虽然它们可能会带着其他的质量属性目标来权衡这个响应)。模式,相比之下,通常专注在解决和平衡多个力量(force)——多个质量属性目标。用类推的方式,可以说策略是原子级的,而模式则是分子级的。

策略提供了一种自顶向下的设计思维。一个策略类别目录始于和一个质量属性完成相关的一套设计目标,并呈现给软件架构师一套选项以从中选择策略。随后这些选项需要通过一些模式组合、框架和编码,被进一步实例化。

例如,在图2.9中,性能设计对象是“控制资源的需求”和“管理资源”。想要创建“优秀”性能的设计的软件架构师需要选择一个或者多个选项。就是说,软件架构师需要决定,控制资源的需求是否可行,管理资源是否可行。在某些系统中,事件到达该系统时是可控、可按优先级排序的,或者可以用某些方法来限制。如果不可行,那软件架构师能管理的资源仅仅是试图产生响应中的一部分,并伴随着可接受的时间约束。在“管理资源”的范畴中,软件架构师可以选择增加资源、引起并发、保留多份运算、保留多份数据等。接着这些策略需要被实例化。举个例子,一个软件架构师可能选择了半同步/半异步模式(参看图2.5)作为引起(或保留)并发的方法,或者选择负载平衡群集(参看图2.7)来保留多份运算。所以我们会在第3章了解到,选择、组合、制定策略及模式都是ADD流程的关键步骤。这里有策略类别目录专门针对质量属性的可用性、互操作性、可修改性、性能、安全、可测试性、可用性。

图2.9 软件架构实例中的性能决策

2.5.5 外部开发组件

模式和策略是从自然中抽象出来的。然而,当设计软件架构时,你需要使用这些设计概念来具体化架构,并且要更加靠近真实的实现情况。通过两个方法可以达到这一点:可以从策略和模式中获得的元素进行编号,或者给架构中的一个或多个元素分配技术。作为一个软件架构师,你要做的最重要的其中一个决定就是到底是“买一个还是自建一个”的选择。

我们把技术认定为是外部开发的组件,因为这些组件不会作为开发项目的一部分来创建。这里有几种外部开发组件的类型:

❑ 技术家庭组。一个技术家庭组就是一组具有常见功能性用途的特定技术。它可以作为一个占位符直到一个特定的产品或框架被确定选择了。例如,一个关系数据库管理系统(RDBMS)或者基于对象的关系映射(ORM)。图2.10展示了在大数据领域的不同技术家庭组(正常文本字体)。

图2.10 大数据应用领域的技术家庭组树结构

❑ 产品。产品(或者软件包)指的是一个能集成在系统中的独立的软件功能块,该系统正在被设计并且仅仅要求非常少量的配置或代码。例如,一个关系数据库管理系统,如Oracle或者微软SQL服务器。图2.10所示为大数据领域的不同产品(斜体字)。

❑ 应用框架。一个应用框架(或者就是框架)是可重用的软件元素,由模式和策略构成,它提供了通用的功能来定位重复范围和大范围应用的质量属性关注点。经过精心选择和正确实施的框架,可以提高程序员的生产效率。这是通过使程序员能够专注于业务逻辑以及终端用户的价值来达到的,而不是底层技术及其具体实现方法。与产品相反的是,框架功能通常可以从应用程序代码中调用,或者是利用一些面向方面的方法类型来“注入”。框架一般要求大量的配置,基本上是通过XML文件或者其他诸如Java注释这样的方法来做。举个框架的例子,Hibernate是一个在Java中用来实施面向对象关系映射的框架。有几类可用的框架类型:全栈(满堆栈)框架,如Spring通常和参考体系架构相关,通过贯穿参考架构的不同元素来获得常见的关注点;非全栈框架,如JFS获得的是特定功能或质量属性的问题。

❑ 平台。平台提供一个完整的基础设施,在基础设施上建立和执行应用程序。平台的例子包括Java、.Net或者Google云。

外部开发组件的选择,是设计过程中的一个关键点,因其数量大而变成了一个具有挑战性的任务。这里有几个标准是你在选择外部开发组件时应该要考虑的:

❑ 寻找的问题。这个问题是特定的吗?例如,是针对关系映射面向对象的框架问题,还是一些更普遍的问题呢,如平台?

❑ 成本。许可证的成本是多少?如果是免费的,支持成本和教育培训成本又是多少?

❑ 许可证类型。有和产品目标兼容的许可证吗?

❑ 支持。外部开发组件的支持如何?有相关技术的扩展文档吗?存在扩展用户或者开发社区,来寻求建议和帮助吗?

❑ 学习曲线。学习这个技术有多难?你所在的团队组织是不是已经有人掌握了这项技术?有现成的课程吗?

❑ 成熟度。这个技术是市场中新兴的吗?会不会可能很新潮但是相对不太稳定或者没有支持呢?

❑ 流行度。这个技术是相对广泛传播的吗?有被成熟的组织积极地推荐或者采纳吗?雇用具有该技术深度知识的人容易吗?有没有一个活跃的开发社区或者用户群体?

❑ 兼容性和集成的容易度。和其他运用在项目中的技术兼容吗?能被容易地集成到项目中吗?

❑ 对关键质量属性的支持。这项技术对性能属性有限制吗?安全又可靠吗?

❑ 规模。技术的应用会不会对开发的应用规模有负面影响?

不幸的是,这些问题的答案通常不太容易回答,并且对特殊技术的选择可能要求你做一些研究,或者,最终你要去创建一个原型,以便在筛选过程中辅助你。这些标准也会对总体拥有成本有明显的影响。