软件体系结构尚处在发展期,对于其定义,目前学术界尚未形成统一意见,不同学者有不同的看法。以下介绍并分析几个具有代表性的定义。
体系结构是以构件、构件之间的关系、构件与环境之间的关系为内容的某一系统的基本组织以及指导上述内容设计与演化的原理,即
软件体系结构={构件,连接件,环境,原理}
体系结构是一系列重要决策的集合,这些决策与以下内容相关:软件的组织、构成系统的结构元素及其接口的选择,这些元素在相互协作中明确表现出的行为、这些结构元素和行为元素进一步组合构成的更大规模的子系统,和引导这一组织(包括这些元素及其接口、它们的协作、它们的组合)的体系结构风格,即
软件体系结构={组织,元素,子系统,风格}
程序或计算系统的软件体系结构是系统的一个或多个结构,包括软件构件、构件的外部可视属性和构件之间的关系。这个定义有以下含义:首先,体系结构定义了构件,描述了构件间如何交互,这意味着体系结构略去了那些仅与某构件自身有关的信息。同时,这个定义明确指出系统可以包含多个结构,但没有其中的哪一个可以被称为是体系结构。这个定义还意味着每一个软件系统都有一个体系结构,因为每个软件系统都是由若干构件及其之间的关系构成的。此外,只要一个构件的行为可以被其他构件观察或辨明,这个构件就是体系结构的一部分。
这里的外部可视属性,是指其他构件认为该构件所具备的特征,如所提供的服务、具有的性能特点、错误处理机制、共享资源的用法等。需要注意的是,此定义中,特意未指明什么是构件,什么是关系。构件既可以是对象,也可以是进程,还可以是函数库或是数据库。
在第一届软件系统体系结构国际研讨会上,Mary Shaw对于当时术语使用的混乱情况予以了澄清:不同学者的软件体系结构定义之间并不相互抵触,在回答什么是软件体系结构这样的问题时,也并没有根本的冲突。实际上,它们代表了软件体系结构研究者对于体系结构研究重点的一系列不同看法。在会上,Shaw对当时的各种观点做了如下的分类。
(1) 结构模型:结构模型认为,软件体系结构由构件、构件之间的连接和一些其他方面组成。这些方面包括如下几类:
· 配置,风格;
· 约束,语义;
· 分析,属性;
· 原理,需求。
(2) 框架模型:框架模型的观点与结构模型相似,但其重点在于整个系统的连贯结构(这种结构通常是唯一的),这与重视其组成恰好相反。框架模型常以某种特定领域或某类问题为目标。
(3) 动态模型:动态模型强调系统的行为质量。“动态”可以有多种含义。它可以是指整个系统配置的变化,也可以是指禁止预先激活了的通信或交互,还可以是指计算中表现出的动态特性,如改变数据的值。
(4) 过程模型:过程模型关注系统结构的构建及其步骤和过程。在这一观点下,体系结构是所进行的一系列过程的结果。
软件体系结构={构件,连接件,约束}
(1) 构件(Component)可以是一组代码,如程序的模块,也可以是一个独立的程序,如数据库服务器。构件是相关对象的集合,运行后实现某计算逻辑。它们或是结构相关或是逻辑相关。构件相对独立,仅通过接口与外部相互作用,可作为独立单元嵌入到不同应用系统中。构件的定制和规范化对于实现构件的重用有重要意义。
(2) 连接件(Connector)可以是过程调用、管道、远程过程调用等,用于表示构件之间的相互作用,它把不同的构件连接起来构成体系结构的一部分。连接件也是一组对象。它一般表现为框架式对象或转换式对象(调用远程构件资源),例如“桩”、“代理”对象等。
(3) 约束(Constrain)一般为对象连接时的规则,或指明构件连接的姿态和条件。例如,上层构件可要求下层构件的服务,反之不行;两个对象不得以递归方式发送消息;代码复制迁移的一致性约束;在什么条件下此种连接无效等。主要针对连接件的一些约束规则。
软件体系结构是一组具有特定形式的体系结构元素(Elements)。这组元素分为3类:负责完成数据加工的处理元素(Processing Elements)、被加工的数据元素(Data Elements)和用于把体系结构的不同部分组合连接到一起的连接元素(Connecting Elements)。软件体系结构形式由专有特性和关系组成。专有特性用于限制软件体系结构元素的选择,关系用于限制软件体系结构元素组合的拓扑结构。在多个体系结构方案中选择合适的体系结构方案往往基于一组准则,即
软件体系结构={元素,形式,准则}
1995年,David Garlan和Dewne Perry在IEEE软件工程学报上所做的特约评论中提出:软件体系结构是一个程序或系统各构件的结构、它们的相互关系以及进行设计的原则和指导方针,这些原则和方针随时间变化而变化。
软件体系结构包括系统构件、连接件、约束的集合,反映不同人员需求的集合,以及准则的集合。其中,这些准则能够说明由构件、连接件和约束所定义的系统在实现时是如何满足系统不同人员需求的,即
软件体系结构={构件,连接件,约束,不同人员的需求,准则}
比较上述体系结构定义,可以发现:尽管各种定义都从不同的角度关注软件体系结构,研究对象各有侧重,但其核心内容都是软件的系统结构,并且都蕴含构件、构件之间的关系、构件和连接件之间的关系等实体。
根据国内普遍认可的看法,可以将体系结构定义为构件、连接件和约束。软件体系结构指可预制和可重构的软件框架结构。构件是可预制和可重用的软件部件,是组成体系结构的基本计算单元或数据存储单元;连接件也是可预制和可重用的构件部件,是构件之间的连接单元;构件和连接件之间的关系用约束来描述。这样就可以把软件体系结构写成:
体系结构(Architecture)=构件(Components)+连接件(Connectors)+约束(Constraints)
除了构件、连接件和约束这3个最基本的组成元素,软件体系结构还包括端口(Port)和角色(Role)两种元素。构件作为一个封装的实体,仅通过其接口与外部环境交互,而构件的接口由一组端口组成,每个端口表示了构件和外部环境的交互点。连接件作为建模软件体系结构的主要实体,同样也有接口。连接件的接口由一组角色组成,连接的每个角色定义了该连接表示的交互的参与者。图2-1形式化地描述了软件体系结构的基本概念。
图2-1 软件体系结构的基本概念
其中:
软件体系结构∷= 软件体系模型 | 体系结构风格
软件体系模型∷= { 构件,连接件,约束 }
构件∷= { 端口1,端口2,…,端口n }
连接件∷= { 角色1,角色2,…,角色m }
约束∷= { (端口i,角色j),… }
体系结构风格∷= { 管道-过滤器,层次系统,客户/服务器,…,解释器 }
下面,我们对构件、连接件、约束这3个基本概念作进一步的解释。
1.构件
一般认为,构件是指具有一定功能、可明确辨识的软件单位,并且具备以下特点:语义完整、语法正确、有可重用价值。这就意味着,在结构上,构件是语义描述、通信接口和实现代码的复合体。更具体地说,可以把构件视为用于实现某种计算逻辑的相关对象的集合,这些对象或是结构相关或是逻辑相关。在体系结构中,构件可以有不同的粒度。一个构件可以小到只有一个过程,也可以大到包含一个应用程序。它可以包括函数、例程、对象、二进制对象、类库、数据包等。
构件内部包含了多种属性,如端口、类型、语义、约束、演化、非功能属性等。端口是构件与外部世界交互的一组接口。构件端口说明了构件提供哪些服务(消息、操作、变量)。它定义了构件能够提交的计算委托及其用途上的约束。构件类型是实现构件重用的手段。构件类型保证了构件自身能够在体系结构的描述中多次实例化。
从抽象程度来看,构件是对一组类的组合进行封装,并代表完成一个或多个功能的特定服务,也为用户提供了多个接口。构件之间是相对独立的。构件隐藏其具体实现,只通过接口提供服务。如果不用指定的接口与之通信,则外界不会对它的运行造成任何影响。因此,构件可以作为独立单元被应用于不同的体系结构和软件系统中,实现构件的重用。构件的使用与它的开发也是独立的。
2.连接件
连接件是用来建立构件间的交互以及支配这些交互规则的体系结构构造模块。构件之间的交互包括消息或信号量的传递,功能或方法调用,数据的传送和转换,构件之间的同步关系、依赖关系等。在最简单的情况下,构件之间可以直接完成交互,这时体系结构中的连接件就退化为直接连接。在比较复杂的情况下,构件间交互的处理和维持都需要连接件来实现。常见的连接件有管道(在管道-过滤器结构中)、通信协议或通信机制(在客户/服务器结构中)等。
连接件的接口由它与所连接构件之间的一组交互点构成,这些交互点称做角色。角色代表了所连接构件的作用和地位,并体现了连接所具有的方向性。因此,角色存在主动和被动、请求和响应之分。
体系结构级的通信需要有复杂协议来表达,为了抽象这些协议并使之能够重用,可以将连接件构造为类型。
连接件的主要特性有可扩展性、互操作性、动态连接性和请求响应特性。连接件的可扩展性是连接件允许动态改变被关联构件的集合和交互关系的性质。互操作性指的是被连接的构件通过连接件对其他构件进行直接或间接操作的能力。动态连接性是对连接的动态约束,即连接件对于不同的所连接构件实施不同的动态处理方法的能力。请求响应特性包括响应的并发性和时序性。在并行和并发系统中,多个构件有可能并行或并发地提出交互请求,这就要求连接件能够正确协调这些交互请求之间的逻辑关系和时序关系。
对于构件而言,连接件是构件的黏合剂,是构件交互的实现。连接件和构件的区别主要在于它们在体系结构中承担着不同的作用。连接件也是一组对象。它把不同的构件连接起来,形成体系结构的一部分,一般表现为框架式对象或转换式对象(调用远程构件资源)。
3.约束(配置)
体系结构的约束描述了体系结构配置和拓扑的要求,确定了体系结构的构件与连接件的连接关系。它是基于规则和参数配置的。体系结构约束提供限制以确定构件是否正确连接、接口是否匹配、连接件构成的通信是否正确,并说明实现所要求行为的组合语义。
体系结构往往用于大型的、生存期长的软件系统的描述。为了更好地在一个较高的抽象层上理解系统的分析和设计,同时为了方便系统开发者、使用者等多种有关人员之间的交流,需要简单的、可理解的语法来配置结构化(拓扑的)信息。理想的情况是从约束说明中澄清系统结构,即不需研究构件与连接件就能使构件系统的各种参与者理解系统。
软件体系结构是软件系统的高级抽象,往往体现了系统开发中最早做出的决策。它体现了根本性的系统设计思路,对系统起着最为深远的影响。体系结构在明确了系统的各个组成部分的同时,也限定了各部分间的交互方式。这将进一步影响到开发资源的配置和开发团队的组织等其他方方面面的开发活动,并影响着最终的软件产品质量。
在大型软件系统中,软件体系结构是决定系统能否顺利实现的关键因素之一,不当的体系结构会给整个系统带来灾难性的后果。
良好的体系结构对于软件系统的重要意义在软件生命周期中的各个阶段都有体现,这主要有如下4个方面。
1.对系统分析的意义
在系统分析阶段,软件体系结构发挥着巨大作用。
一方面,借助于软件体系结构进行描述,可以使问题得以进一步抽象,使整个系统更易于被系统分析设计人员把握,更清晰地认识系统,完善对系统的理解。除此之外,体系结构对于系统分析带来的优势还体现在,它为系统分析设计人员提供了新的思路。比如,在更高层次上进行系统一致性检查、使用成熟的软件体系结构风格等。
另一方面,它能够帮助软件系统的各有关权益方(客户、用户、项目管理人员、设计开发人员以及测试人员等)形成统一认识,互相交流。交流是软件开发的重要组成部分。在软件开发活动中,各有关权益方承担着不同角色,关注同一软件系统不同的侧面,这要求他们要从不同的角度交流对共同面对的软件系统的认识。
例如,用户关心系统是否满足可用性及可靠性需求;客户关心此结构能否按期按预算实现;管理人员担心在经费支出和进度条件下,按此体系结构能否使开发组成员在一定程度上独立开发,并有条不紊地有序地交互;开发人员关心达到全部目的的策略。体系结构代表了系统的公共的高层次的抽象,是大家都关心的一个重要因素。它作为项目参与人员共同使用的语言,还具有很强的描述能力,起到了难以替代的沟通作用。系统的大部分有关人员(即使不是全部)能把它作为建立互相理解的基础,通过体系结构的概念、术语和规范,设计者与用户之间、设计者之间等各方面相关人员可以更好地彼此理解。
2.对软件开发的意义
软件体系结构代表了系统早期的设计决策。与开发、设计、编码或运行服务及维护阶段相比,早期设计决策的处理难度最大,对系统的生命期的影响也最大。同时,软件体系结构也难于改变,会对整个系统开发活动造成深远影响。
软件体系结构是系统实现的基本约束,即系统的后继开发工作要遵循体系结构所描述的设计决策。每个构件或连接件必须满足体系结构规格说明中指定的功能、语义和接口,并且按体系结构配置中所规定的方式完成交互。这样,构件或连接件的开发人员在体系结构给定的约束下进行工作,他们既不关心其他构件或连接件的开发,也不会对其产生影响。而体系结构设计者也不必设计算法或精通编程语言。
软件体系结构决定了开发和维护项目的组织活动。软件体系结构也会反映到开发工作的分解,以及项目的人员组织。项目组成员还要使用构件的接口规格说明相互交流。即使到了维护期,项目维护人员的组织形式也常常要依据特定的软件体系结构成分来安排。此外,对于项目组新成员,可以用软件体系结构作为培训基础或高层次的系统概述,使他们迅速、准确地认识系统和自己的任务,快速进入开发角色。
软件体系结构对于软件质量控制有重要意义。软件质量特性可分为两类:第一类是可以通过运行软件并观察其效果来度量的特性,如功能、性能、安全性及可靠性等;第二类是指那些无法通过观察系统来度量,只能通过观察开发活动或维护活动来考察的特性,包括各种可维护性问题,如可适应性、可移植性、可重用性等(例如,可重用性依赖于系统中的构件与其他构件的联系情况)。软件体系结构在很大程度上确定了系统是否能达到其需求的质量特性。
使用软件体系结构的一些评估技术(如SAAM),对软件体系结构加以分析,能够对软件的某些质量特性加以预测。但同时,也必须认识到,好的软件体系结构是成功的必要条件,但不是充分条件。仅重视软件体系结构并不能保证系统所要求的功能和质量——低劣的设计及实现都会损害整个体系结构。
3.对软件重用的意义
重用是提高软件开发效率、保证软件质量的重要手段。软件开发经历了从机器语言、汇编语言、结构化程序设计语言、面向对象程序设计语言、形式化(非形式化)规格说明语言(如体系结构描述语言)的发展过程,越来越适合开发人员的思维活动模型,代码重用的级别也在不断地提升。体系结构技术的研究,使软件重用从代码重用发展到设计重用和过程重用,实现多层次的软件重用。
构件的重用是体系结构良好的软件系统最基本的一点。面向体系结构的开发方法常常注意构件的组合与装配,而不一定把编程作为主要活动。有效地利用标准构件,或是识别并重用系统内部的构件,或是购买第三方构件,只要这些构件与当前体系结构相容,都能减少开发中的重复劳动和系统中的重复代码。体系结构起了组织产品的构件、接口及运行的作用。这里要着重指出的是标准构件的应用。应用标准构件库的关键在于要能够从整体上对库中构件进行把握。一旦做到了这点,就可以快速、灵活地在构件库中选择出合适的构件应用到系统中去;反之,构件的选取就只能通过反复地浏览来寻找,这实际上影响到了体系结构所带来的优势,造成了不必要的资源浪费。
体系结构良好的软件系统中,不仅构件库能够重用,还可以在更高层次上实现软件子系统乃至软件系统框架的重用。软件体系结构级的重用意味着体系结构的决策能在具有相似需求的多个系统中发生影响,这比代码级的重用要有更大的好处。通过对体系结构的抽象可以使设计者能够对一些实践证明有效的体系结构构件进行重用,从而提高设计效率和可靠性。在设计过程中我们常常会发现,对一个体系结构构件稍加抽象,就可以将它应用到其他设计中去,这样会大大降低设计的复杂度。
例如,我们在某个设计中采用了管道-过滤器风格,当我们将系统映射到Unix系统中时,我们就会发现Unix系统已经为我们提供了功能丰富的管道-过滤器功能,这样我们就可以充分利用Unix系统提供的这些构件来简化我们的设计和开发。当前,针对特定领域的体系结构,人们开展了许多研究和实践工作。这在某种意义上也是一种重用。软件重用的层次越高,所带来的收益也就越大。某些情况下,重用的设计方案本身也许不是最适合该系统的,但是从整体上权衡,通过重用带来的成本节约和质量提供能够让重用变得非常值得。
软件体系结构有利于形成完整的软件生产线。1976年Parnas提出了发展软件族的软件生产线。软件族的软件生产线成功的关键问题是设计决策的次序问题,要求对于最容易发生变动的决策应当尽量放在最迟作出。事实上,软件族的软件生产线代表了早期决策的总和,将影响软件族的软件生产线的全体成员。可以说,体系结构在一定程度上限制了设计选择的范围或内容。要认识到这种决策对于每一个部分来说不一定是最优,但其优点一般可以补偿失去的特定领域优化的损失。
4.对系统演化的意义
对软件系统的演化过程中,维护人员需要不断地进行调整、修改、增加新的功能或构件等工作。通常情况下,软件系统的开发成本中,有80%是在初次投入使用之后产生的。因此,解决好系统演化阶段的开发问题具有重要意义。
软件体系结构决定着系统构件的划分和交互方式。一方面,在设计系统的体系结构之初,就应当充分考虑到将来可能的系统演化;另一方面,在进行系统演化阶段的开发时,由于体系结构充分地刻画了当前系统,清晰地描述了构件及其相互关系和整个系统的框架,所以应当充分利用。
以现有体系结构为基础,把握需要进行的系统变动,在系统范围内综合考虑,有助于确定系统维护的最优方案,更好地控制软件质量和维护成本。软件为主的系统总是存在着“利用软件作为增加或修改系统总体功能的工具”的倾向。重要的是要决定何时进行改动,确定哪种改动风险最小,评估改动的后果,仲裁改动的顺序及优先级。所有这些都需要深入地洞察系统各部分的关系、相互依存关系、性能及行为特性。而在软件体系结构这一级进行讨论,就能提供这种观察力,更重要的是软件体系结构可以把可能发生的变动分为3类:局部的、非局部的和体系结构级的。
局部的是指只要修改单个构件本身;非局部的是指要修改几个构件,但不影响基础体系结构的变动;而体系结构级是指会影响各部分的相互关系,甚至要改动整个系统。显然,局部改动应是最经常发生的,也是最容易进行的。软件体系结构承担了“保证最经常发生的变动是最容易进行的”这一重任。
软件工程作为一门独立的学科,其发展已逾30年。无论从应用规模还是从技术水平看,计算机软件产业所经历的发展都是迅猛的。这体现在诸多方面。首先,软件系统的应用领域从实验室渗透到了人类社会的各个角落。最初的软件是以穿孔纸带或卡片的形式出现在实验室和机房中用于科学计算的;而在今天的人类社会中,各种软件系统运行在从手持设备(如手机)到大型机(如进行天气预报的服务器)的各种规模和用途的信息处理设备上。其次,软件系统的规模也迅速增长。
从微机不断跃增的内存配置就可以明显看出这一点。1981年,IBM公司推出的第一台PC机的配置是16 KB的内存;2003年,主流PC机的内存配置是256 MB;2008年,主流PC机的内存配置是2 GB。此外,随着计算机产业的发展,软件成本也在增长。20世纪50年代,软件成本在整个计算机系统成本中所占的比例为10%~20%。到20世纪60年代中期,软件成本在计算机系统中所占的比例已经增长到50%左右。相反,计算机硬件价格随着技术进步和生产规模扩大却在不断下降。软件成本在计算机系统中所占的比例越来越大。
下面是一组来自美国空军计算机系统的数据:1955年,软件费用约占总费用的18%,1970年达到60%,1975年达到72%,1980年达到80%,1985年达到85%左右。
在软件应用规模和应用领域迅速扩大的同时,软件开发技术也在发生着根本性的变革。软件规模的迅速增长使得软件开发成为了一项过去难以想象的系统工程。根据微软公司公布的数据, Windows 2000开发过程中测试用代码行数超过1000万行,测试兼容性的应用软件数量约1000种,应用软件测试中所使用的脚本程序约6500种,每月备份的数据约88?TB,每晚模拟打印数量约25万页,每周刻录CD约12 000盘。
在此过程中,软件体系结构也经历了与之相对应的一系列变革,由最初的模糊概念发展成为一门日益成熟的技术。下面我们分阶段进行讨论。
1946年,随着具有里程碑意义的ENIAC机的问世,软件行业开始在美国和欧洲的实验室出现。1955~1965年间,运算速度越来越快、价格越来越低的新计算机不断涌现。这期间的软件多数应用于学术界,或者是政府、军队及私人公司。但是,由于当时的计算机硬件向着专用方向发展,科学与商业领域使用完全不同的机器硬件。不断地针对不同计算机编写软件让软件工作人员应接不暇,反复地开发相同或类似的软件使得软件研究者开始着手处理软件的移植问题,即设法使一种机器的汇编语言程序能够自动移植到另一台机器上去。但研究人员很快发现这难以实现,大量复杂代码仍必须由程序员进行改写。
在这样的背景下,高级语言应运而生。FORTRAN语言诞生于20世纪50年代中期,是最早发布的高级语言;50年代后期,COBOL语言出现;60年代早期,ALGOL语言出现。而在当时,高级语言不能被程序编制人员所接受,他们认为真正的程序员应使用汇编语言。
总的说来,20世纪70年代以前,尤其是在以ALGOL 68为代表的高级语言出现以前,软件开发基本上都是用汇编程序设计。尽管此阶段软件工作者开始逐渐形成模块编程的方法,但软件投入的资金和人力无法预测,软件完工的时间无法确定,软件的可靠性无法控制等问题开始表露出来,软件危机从此阶段开始出现。一个著名的例子是1962年7月美国飞往金星的火箭控制系统中的指令,“DO 5 I=1, 3”误写成“DO 5 I=1.3”,导致火箭偏离轨道,被迫炸毁。
因为此阶段系统规模较小,很少明确考虑软件体系结构,所以一般不存在软件系统的建模工作。
原文:https://www.cnblogs.com/ZanderZhao/p/11473829.html