1.2 架构结构和视图

本文探讨了软件架构中的不同视角和结构,包括模块结构、组件和连接器结构以及分配结构。模块结构关注代码单元的组织和依赖,组件和连接器结构展现运行时行为和交互,分配结构描述软件与硬件、团队和文件系统的映射。每个结构服务于不同的设计决策和质量属性分析,如可修改性、并发性和性能。架构师通过选择和设计这些结构来影响系统的特性,并在不同视图之间建立关联,以实现全面的系统理解。
摘要由CSDN通过智能技术生成

        神经科医生、骨科医生、血液科医生和皮肤科医生对人体结构都有不同的看法。眼科医生、心脏病专家和足病学家专注于特定的子系统。运动学家和精神病医生关注整个安排行为的不同方面。尽管这些视图的描述方式不同,属性也非常不同,但它们都有内在的联系:它们共同描述了人体的结构。图1所示。显示人体的几种不同的视图:骨骼、血管和x光。

        软件也是这样。现代系统往往过于复杂,无法一次掌握全部。相反,我们将注意力限制在软件系统的一个(或一小部分)结构上。为了对架构进行有意义的交流,我们必须弄清楚我们正在讨论的架构,以及我们对架构的看法。

        结构和视图

        在讨论架构表示时,我们将使用相关术语“结构”和“视图”。

  • 视图是一个由系统干系人编写和读取的的互相耦合的架构元素集合的表示。它由一组元素的表示以及它们之间的关系组成。
  • 结构是元素本身的集合,因为它们存在于软件或硬件中。

        简而言之,视图是结构的表示。例如,模块结构是系统模块及其组织的集合。模块视图是该结构的表示,根据模板以选定的符号记录,并由一些系统涉众使用。所以:架构师设计结构。它们记录了这些结构的视图。

        三种结构

        如前面章节所示,架构结构可以被分为三个主要类别,这取决于它们所显示的元素的广泛性质。这些与架构设计涉及的三大类决策相对应:

        1 模块结构体现了关于如何将系统构造为一组必须构建或采购的代码或数据单元的决策。在任何模块结构里,元素都是某种类型的模块。(可能是类、层级或者仅仅功能的分配,所有这些都是实现单元)。模块代表了考虑系统的静态方式。模块是指定的功能职责区域;在这些结构中,很少强调结果软件在运行时如何表现自己。模块结构允许我们回答如下问题:

        (1) 分配给每个模块的主要功能职责是什么?        

        (2) 模块允许使用哪些其他软件元素?

        (3) 它实际使用和依赖的其他软件是什么?

        (4) 哪些模块通过泛化或专门化(即继承)关系与其他模块相关?

        模块结构直接传达了这些信息,但它们也可以被扩展用来询问当分配给每个模块的职责发生变化时对系统的影响。换句话说,检查系统的模块结构,即查看其模块视图,是推断系统可修改性的一个极好方法。

        2 组件和连接器结构体现了关于如何将系统构造为一组具有运行时行为(组件)和交互(连接器)的元素的决策。在这些结构中,元素是运行时组件(它是主要的计算单元,可以是服务、对等点、客户端、服务器、过滤器或许多其他类型的运行时元素)和连接器(它们是组件之间的通信工具,例如调用返回、进程同步操作符、管道或其他)。组件和连接器视图回答了以下问题:

        (1) 主要执行组件是什么?它们是如何在运行时交互的?

        (2) 主要共享数据存储是什么?

        (3) 哪些系统部分是复制的?

        (4) 数据是如何通过系统进行的?

        (5) 系统的哪些部分是可以并行运行的?

        (6) 系统结构可以在执行时变化吗?如何可以的话,是如何变化的?

        此外,组件和连接器视图对于询问有关系统运行时属性(如性能、安全性、可用性等)的问题至关重要。

        3 分配结构体现了系统如何与其环境中的非软件结构(如CPU、文件系统、网络、开发团队等)相关的决策。这些结构显示了软件元素与创建和执行软件的一个或多个外部环境中的元素之间的关系。分配视图回答了以下问题:

        (1) 每个软件元素在哪个处理器上执行?

        (2) 在开发、测试和系统构建期间,每个元素存储在哪些目录或文件中?

        (3) 每个软件元素分配给开发团队的任务是什么?

        架构提供了洞察力

        结构因为其分析和工程能力在软件架构的远景中扮演了重要角色。每个结构提供了一个推理相关质量属性的透视图。例如:

        (1) 模块使用结构,体现了哪些模块使用了哪些其他模块,它与系统扩展或收缩的容易程度密切相关。

        (2) 并发结构体现了系统内的并行性,它与使系统摆脱死锁和性能瓶颈的容易程度密切相关。

        (3) 部署结构与性能、可用性和安全目标的实现密切相关。

        每个结构都为架构师提供了对设计的不同见解(也就是说,可以分析每个结构是否具有交付质量属性的能力)。但也许更重要的是,每种结构都为架构师提供了一个工程杠杆点:通过适当地设计结构,可以获得所需的质量属性。

        第4章中描述的场景对于练习给定结构及其与其他结构的连接非常有用。例如,软件工程师想要更改系统的并发结构,需要查阅并发和部署视图,因为受影响的机制通常涉及进程和线程,而物流可能涉及不同的控制机制,而不是在同一台机器上同时进行的过程。如果需要更改控制机制,则需要咨询模块分解以确定更改的程度。

        常用的模块结构

        常用的模块结构包含以下:

        (1) 分解结构。单元是通过is-a-submodule-of的关系相互关联的模块,展示模块是如何被递归地分解到小模块直到模块小到足够被简单理解。由于架构师列举了软件单元必须实现的部分,以及为下一步(更详细的)设计和最终实现分配了每个条目到模块,在这种结构中的模块代表着一个公共的设计起始点。模块通常有与其相关的产品(例如接口规范、代码、测试计划等)。分解结构通过确保可能的更改是局部变更在很大程度上决定了系统的可修改性。也就是说,更改属于最多几个(最好是小的)模块的范围。这种结构经常被用于开发项目组织的基础,包括文档的结构,以及项目集成和测试计划。此结构中的单元往往具有特定于组织的名称,如“段”或“子系统”。

        (2) 使用结构。在这个重要的,但被忽视的结构中,单元即模块或者类。单元被用户关系(一种特殊形式的依赖关系)关联。如果第一个软件单元的正确性要求第二个软件单元有一个正常运行的版本(与存根相反),则一个软件单元使用另一个软件单元。使用结构被用于可以被扩展用于添加功能的工程系统,或从中提取有用功能子集的系统。简单创建系统子集的能力允许用于提升开发能力。

        (3) 层状结构。该结构中的模块被称为层。层是一个抽象的,通过托管接口提供了一级内聚服务的“虚拟机”。层允许在一个严格的管理方式下使用其他层;在一个严格分层的系统中,层只允许使用紧靠其下方的层。这种结构用于赋予系统可移植性,即改变底层计算平台的能力。

        (4) 类(或概括)结构。模块单元在本结构中被称为类。该关系是“继承至”或者“是一个实例”。该视图支持对相似行为或功能的集合(例如,其他类继承自的类)和参数化差异进行推论。类结构允许人们对重用和功能的增量添加进行推理。如果一个项目遵循了面向对象的分析和设计过程,那么它通常就是这种结构。

        (5) 数据模型。数据模型根据数据实体及其关系描述静态信息结构。例如,在银行系统中,实体通常会包含账号、客户以及贷款。账号有多个属性,例如账户、类型(储蓄或支票)、状态及当前余额。关系可能规定一个客户可以拥有一个或多个帐户,并且一个帐户与一个或两个客户关联。

        常用的组件及连接器结构

        组件和连接器结构展示了一个系统的运行时视图。上述所描述的结构的模块都已编译成可执行形式。因此,所有组件和连接器结构都与基于模块的结构正交,并处理运行系统的动态方面。所有组件和连接器结构中的关系都是附件,展示了组件和连接器是如何连接在一起的(连接器本身可以是熟悉的构造,例如“invokes”)。常用的组件和连接器结构包含以下:

        (1) 服务结构。服务结构中的单元都是通过服务协同机制例如SOAP互相交互的服务。服务结构是帮助设计由组件组成的、可能被匿名或独立开发的系统的重要结构。

        (2) 并行结构。这种组件及连接器结构允许架构师决定并行性机会以及资源争夺可能发生的位置。单元是组件,而连接器是它们的通信机制。组件被安排成逻辑线程;一个逻辑线程是一个可以在后续的设计过程中被分配到不同物理线程的计算序列。并行结构在设计过程早期,被用于确定管理并行执行相关问题的需求。

        常用的分配结构

        分配结构定义了元素如何从组件和连接器或者模型结构地图到非软件事物上:通常是硬件、团队及文件系统。常用的分配结构包括:

        (1) 部署结构。部署结构展示了如何将软件分配到硬件进程及通信元素。元素是指软件元素(通常是组件和连接器视图的一个过程)、硬件实体(处理器)和通信通道。关系是allocated-to关系,展示在软件元素驻留的或当动态分配时转移到的物理单元上。该结构可以被用于性能、数据完整性、安全和可用性的推论上。它在分布式系统和并发系统特别重要。

        (2) 实现结构。该结构展示了如何将软件元素(通常是模块)在系统开发、集成或配置控制环境中映射到文件结构中。这对于开发活动和构建过程的管理至关重要。(在实践中,管理实现环境的开发环境工具的屏幕截图通常是实现视图的非常有用和充分的图表)

        (3) 工作分解结构。该结构将实施和集成模块的责任分配给执行模块的团队。架构设计中的工作分解结构使得架构更为清晰地表明,关于谁做的工作的决定具有体系结构和管理含义。架构师将知道每个团队的专业知识需求。同样,在大型的多源分布式开发项目中,工作分解结构是调用具有功能共性的单元并将其分配到单个团队的手段,而不是让每个需要这些功能的人去实现它们。该结构也会决定团队间的主要通信通道:常规的远程会议、wiki、电子邮件列表等等。

        下表概括了这些结构,该表中列举了在每个结构中的元素及关系的含义,并展示了每个结构的使用场景:

        相互关联的结构

        以上所描述的每种结构都为系统提供了不同的视角和设计处理,并且每种都是被验证过的,都在不同场景下能起到巨大作用的。虽然这些结构有着不同的系统视角,但它们并不是互不相干的。一个结构的元素将与另一个结构的元素产生关联,而我们需要解释这种关联。例如,分解结构中的模块可以表现为组件和连接器结构中的一个或多个组件,反映其运行时的另一面。通常,结构间的映射是多对多的。

        下图展示了两个结构互相关联的一个非常简单的例子。左图展示了微客户服务系统的一个模块分解视图。这个系统必须实现两个模块:客户端和服务端。右图展示了同一微客户服务系统的组件和连接器视图,在运行时,有十个客户端正在运行和访问服务端。所以,这个小系统有两个模块和11个组件(以及10个连接器)。

        虽然分解结构中的元素和客户服务结构中的元素之间的对应关系是很明显的,但这两个视图是用于不同场景的。例如,右侧的视力可以用在性能分析、瓶颈预测,以及网络流量管理中,这些对于左侧视图来说非常困难,基本上是不可能的。(后续我们会阐述map-reduce模式,在该模式中,简单、相同功能的副本分布在成百上千个处理节点上——整个系统的一个模块,但每个节点一个组件。)个别项目有时候会考虑一个结构为主,其他结构为辅,如果有可能的话,会把其他结构作为主结构的一个子项。而分解结构通常就作为主结构。这有一个很好的解释:分解结构更趋向于产生项目结构,因为它反映了开发的团队结构。除此之外,C&C结构(组件和连接器结构)也可能作为主结构,因为它展示了系统功能和/或关键质量指标是如何被实现的。 

        越少越好

        并非所有系统都需要考虑许多架构结构。系统越大,这些结构之间的差异就越明显;但对于小型系统我们通常可以用更少的资源来解决问题。与使用多个组件与连接器结构中的每一个不同,通常使用单个组件和连接器结构即可。如果只有一个进程,那么这个进程结构只是单个节点,并且不需要明确表现在设计中。如果不需要进行分布式(即系统被实现为单体服务),那么部署结构就很简单,且不需要进一步考虑。通常情况下,只有能带来正向的回报(通常是降低开发或维护成本)时,才会进行结构的设计和归档。

        如何选择结构?

        我们简单描述了一些常用的架构结构,除此之外,还有更多结构。那么,在做架构设计时如何选择呢?当然不是选择所有结构。后文我们会进行更深入的探讨,我们只需要知道,你需要考虑各种结构在系统的更重要的质量指标中为你提供了哪些洞察力和影响力,然后选择那个在交付这些指标时能扮演最好角色的那个。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值