软件体系结构建模的种类。
结构模型。
最直观、最普遍的建模方法。这种方法以体系结构的构件、连接件和其他概念来刻画结构,并力图通过结构来反映系统的重要语义内容,包括系统的配置、约束、隐含的假设条件、风格、性质等。
研究结构模型的核心是体系结构描述语言。
框架模型。
框架模型与结构模型类似,但它不太侧重描述结构的细节而更侧重于整体的结构。
框架模型主要以一些特殊的问题为目标建立只针对和适应该问题的结构。
动态模型。
动态模型是对结构或框架模型的补充,研究系统的“大颗粒”的行为性质。
例如,描述系统的重新配置或演化。动态可以指系统总体结构的配置、建立或拆除通信通道或计算的过程。
过程模型。
过程模型研究构造系统的步骤和过程。
结构是遵循某些过程脚本的结果。
功能模型。
功能模型认为体系结构是由一组功能构件按层次组成,下层向上层提供服务。
功能模型可以看作是一种特殊的框架模型。
1. “4+1”模型
Kruchten在1995年提出了4+1的视图模型。
4+1视图模型从5个不同的视角包括逻辑视图、进程视图、物理视图、开发视图和场景视图来描述软件体系结构。
每一个视图只关心系统的一个侧面,5个视图结合在一起才能反映系统的软件体系结构的全部内容。
1.1 逻辑视图
-
逻辑视图主要支持系统的功能需求,即系统提供给最终用户的服务。
-
在逻辑视图中,系统分解成一系列的功能抽象,这些抽象主要来自问题领域。这种分解不但可以用来进行功能分析,而且可用作标识在整个系统的各个不同部分的通用机制和设计元素。
-
在面向对象技术中,通过抽象、封装和继承,可以用对象模型来代表逻辑视图,用类图来描述逻辑视图。
1.2 开发视图
-
开发视图也称模块视图,主要侧重于软件模块的组织和管理。
-
开发视图要考虑软件内部的需求,如软件开发的容易性、软件的重用和软件的通用性,要充分考虑由于具体开发工具的不同而带来的局限性。
-
开发视图通过系统输入输出关系的模型图和子系统图来描述。
在开发视图中,最好采用4-6层子系统,而且每个子系统仅仅能与同层或更低层的子系统通讯,这样可以使每个层次的接口既完备又精练,避免了各个模块之间很复杂的依赖关系。
设计时要充分考虑,对于各个层次,层次越低,通用性越强,这样,可以保证应用程序的需求发生改变时,所做的改动最小。开发视图所用的风格通常是层次结构风格。
1.3 进程视图
-
进程视图侧重于系统的运行特性,主要关注一些非功能性的需求。
-
进程视图强调并发性、分布性、系统集成性和容错能力,以及从逻辑视图中的主要抽象如何适合进程结构。它也定义逻辑视图中的各个类的操作具体是在哪一个线程中被执行的。
-
进程视图可以描述成多层抽象,每个级别分别关注不同的方面。在最高层抽象中,进程结构可以看作是构成一个执行单元的一组任务。它可看成一系列独立的,通过逻辑网络相互通信的程序。它们是分布的,通过总线或局域网、广域网等硬件资源连接起来。
1.4 物理视图
-
物理视图主要考虑如何把软件映射到硬件上,它通常要考虑到系统性能、规模、可靠性等。解决系统拓扑结构、系统安装、通讯等问题。
-
当软件运行于不同的节点上时,各视图中的构件都直接或间接地对应于系统的不同节点上。因此,从软件到节点的映射要有较高的灵活性,当环境改变时,对系统其他视图的影响最小。
1.5 场景
-
场景可以看作是那些重要系统活动的抽象,它使四个视图有机联系起来,从某种意义上说场景是最重要的需求抽象。
-
在开发体系结构时,它可以帮助设计者找到体系结构的构件和它们之间的作用关系。同时,也可以用场景来分析一个特定的视图,或描述不同视图构件间是如何相互作用的。
-
场景可以用文本表示,也可以用图形表示。
2. 软件体系结构的核心模型
综合软件体系结构的概念,体系结构的核心模型由5种元素组成:构件、连接件、配置(configuration)、端口(port)和角色(role)。其中,构件、连接件和配置是最基本的元素。
-
构件:
构件是具有某种功能的可重用的软件模板单元,表示了系统中主要的计算元素和数据存储。
构件有两种:复合构件和原子构件。
-
复合构件由其他复合构件和原子构件通过连接而成;
-
原子构件是不可再分的构件,底层由实现该构件的类组成。
-
这种构件的划分提供了体系结构的分层表示能力,有助于简化体系结构的设计。
-
连接件:
连接件表示了构件之间的交互。
简单的连接件如管道(
pipe
)、过程调用(procedurecall
)、事件广播(event broadcast
)等,更为复杂的交互如客户-服务器(client-server
)通信协议、数据库和应用之间的SQL连接等。
连接件作为建模软件体系结构的主要实体,同样也有接口。
连接件的接口由一组角色组成,连接件的每一个角色定义了该连接件表示的交互的参与者,元连接件有两个角色。
例如,
RPC(Remote ProcedureCall
,远程过程调用)的角色为caler
和callee
,pipe
的角色是reading
和writing
,消息传递连接件的角色是sender和receiver。有的连接件有多于两个的角色如事件广播有一个事件发布者角色和任意多个事件接收者角色。
-
配置:
配置表示了构件和连接件的拓扑逻辑和约束。
构件作为一个封装的实体,只能通过其接口与外部环境交互;构件的接口由一组端口组成,每个端口表示了构件和外部环境的交互点。
通过不同的端口类型,一个构件可以提供多重接口。一个端口可以非常简单,如过程调用,也可以表示更为复杂的界面(包含一些约束),如必须以某种顺序调用的一组过程调用。
配置、连接件和构件构成一个3C结构。
3. 软件体系结构的生命周期
3.1 各阶段之间的关系
-
需求分析阶段: 需求分析阶段的任务是根据需求决定系统的功能。
-
在此阶段,设计师应对目标对象和环境作细致深入的调查;收集目标对象的基本信息,从中找出有用的信息。这是一个抽象思维、逻辑推理的过程,其结果是软件规格说明。
-
需求是指用户对目标软件系统在功能、行为、性能、设计约束等方面的期望,需求过程主要是获取用户需求,确定系统中所要用到的构件。
-
体系结构需求包括需求获取、生成类图、对类分组、将类打包成构件和需求评审等过程。
-
需求获取主要是定义开发人员必须实现的软件功能,使得用户能完成他们的任务,从而满足业务上的功能需求。与此同时,还要获得软件质量属性,满足一些非功能需求。
-
获取了需求之后,就可以利用工具自动生成类图,然后对类进行分组、简化类图结构,使之更清晰。
-
分组之后,再要将类打包成构件,这些构件可以分组合并成更大的构件。
-
最后进行需求评审,组织一个由不同代表(例如,系统分析师、需求分析师、系统设计师客户代表、测试人员等)组成的小组,对体系结构需求及相关构件进行仔细的审查。审查的主要内容包括所获取的需求是否真实反映了用户的要求,类的分组是否合理,构件合并是否合理等。
-
-
建立软件体系结构阶段: 在这个阶段,体系结构设计师主要从结构的角度对整个系统进行分析,选择恰当的构件、构件间的相互作用关系以及对它们的约束,最后形成一个系统框架以满足用户需求,为设计奠定基础。
-
在建立体系结构的初期,选择一个合适的体系结构风格是首要的。
-
选择了风格之后,把在体系结构需求阶段已确认的构件映射到体系结构中,将产生一个中间结构。
-
然后,为了把所有已确认的构件集成到体系结构中,必须认真分析这些构件的相互作用和关系。
-
一旦决定了关键构件之间的关系和相互作用,就可以在前面得到的中间结构的基础上进行细化。
-
-
设计阶段: 设计阶段主要是对系统进行模块化并决定描述各个构件间的详细接口、算法和数据类型的选定,对上支持建立体系结构阶段形成的框架,对下提供实现基础。
-
实现阶段:
将设计阶段设计的算法及数据类型进行程序语言表示,满足设计体系结构和需求分析的要求,从而得到满足设计需求的目标系统。
-
整个实现过程是以复审后的文档化的体系结构说明书为基础的,每个构件必须满足软件体系结构中说明的对其他构件的责任。
-
这些决定,即实现的约束是在系统级或项目范围内做出的,每个构件上工作的实现者是看不见的。
-
在体系结构说明书中,已经定义了系统中的构件与构件之间的关系。因为在体系结构层次上,构件接口约束对外唯一地代表了构件,所以可以从构件库中查找符合接口约束的构件,必要时开发新的满足要求的构件。
-
然后,按照设计提供的结构,通过组装支持工具把这些构件的实现体组装起来,完成整个软件系统的连接与合成。
-
最后一步是测试,包括单个构件的功能性测试和被组装应用的整体功能和性能测试。
-
3.2 软件体系结构的生命周期
-
软件体系结构的非形式化描述。
-
在软件体系结构的非形式化描述阶段,对软件体系结构的描述尽管常用自然语言,但是该阶段的工作却是创造性和开拓性的。
-
一种软件体系结构在其产生时,其思想通常是简单的,并常常由软件设计师用非形式化的自然语言表示概念、原则。
-
例如,客户-服务器体系结构就是为适应分布式系统的要求,从主从式演变而来的一种软件体系结构。
-
-
软件体系结构的规范描述和分析
-
软件体系结构的规范描述和分析阶段通过运用合适的形式化数学理论模型对第1阶段的体系结构的非形式化描述进行规范定义,从而得到软件体系结构的形式化规范描述,以使软件体系结构的描述精确、无歧义;并进而分析软件体系结构的性质,如无死锁性、安全性、活性等。
-
分析软件体系结构的性质有利于在系统设计时选择合适的软件体系结构,从而对软件体系结构的选择起指导作用,避免目选择。
-
-
软件体系结构的求精及其验证
-
软件体系结构的求精及其验证阶段完成对已设计好的软件体系结构进行验证和求精。
-
大型系统的软件体系结构总是通过从抽象到具体,逐步求精而达到的;因为一般来说,由于系统的复杂性,抽象是人们在处理复杂问题和对象时必不可少的思维方式,软件体系结构也不例外。
-
过高的抽象却使软件体系结构难以真正在系统设计中实施。因而,如果软件体系结构的抽象粒度过大,就需要对体系结构进行求精、细化,直至能够在系统设计中实施为止。
-
在软件体系结构的每一步求精过程中,需要对不同抽象层次的软件体系结构进行验证,以判断较具体的软件体系结构是否与较抽象的软件体系结构的语义一致,并能实现抽象的软件体系结构。
-
-
软件体系结构的实施
-
软件体系结构的实施阶段将求精后的软件体系结构实施于系统的设计中,并将软件体系结构的构件和连接件等有机地组织在一起,形成系统设计的框架,以便据此实施于软件设计和构造中。
-
-
软件体系结构的演化和扩展
-
当体系结构实施后,就进入软件体系结构的演化和扩展阶段。
-
在实施软件体系结构时,根据系统的需求常常是非功能的需求,如性能、容错、安全性、互操作性、自适应性等非功能性质影响软件体系结构的扩展和改动,这称为软件体系结构的演化。
-
由于对软件体系结构的演化常常由非功能性质的非形式化需求描述引起,因而需要重复第1步;如果由于功能和非功能性质对以前的软件体系结构进行演化,就要涉及软件体系结构的理解,需要进行软件体系结构的逆向工程和再造工程。
-
-
软件体系结构的提供、评价和度量
-
软件体系结构的提供、评价和度量阶段通过将软件体系结构实施于系统设计后。
-
根据系统实际的运行情况,对软件体系结构进行定性的评价和定量的度量,以利于对软件体系结构的重用,并取得经验教训。
-
-
软件体系结构的终结
-
如果一个软件系统的软件体系结构经过多次演化和修改,软件体系结构已变得难以理解,更重要的是不能达到系统设计的要求,不能适应系统的发展。
-
这时,对该软件体系结构的再造工程既不必要,也不可行;说明该软件体系结构已经过时,应该摈弃,以全新的满足系统设计要求的软件体系结构取而代之。
-
这个阶段被称为软件体系结构的终结阶段。
-
4. 补充
-
软件体系结构模型是软件系统结构的表现形式,软件体系结构模型可以分为哪几种?具体是如何划分的?
软件体系结构模型是软件系统结构的表现形式,它可以根据建模的侧重点不同,划分为以下几种类型:
一、结构模型。
结构模型以体系结构的构件、连接件和其他概念来刻画结构,并力图通过结构来反映系统的重要语义内容,包括系统的配置、约束、隐含的假设条件、风格、性质等。
二、框架模型。
框架模型与结构模型类似,但它不太侧重描述结构的细节而更侧重于整体的结构。框架模型主要以一些特殊的问题为目标,建立只针对和适应该问题的结构。
三、动态模型。
动态模型是对结构或框架模型的补充,研究系统的“大颗粒”的行为性质,例如描述系统的重新配置或演化。动态可能指系统总体结构的配置、建立或拆除通信通道或计算的过程。这类系统常是激励型的。
四、过程模型。
过程模型研究构造系统的步骤和过程,因而结构是遵循某些过程脚本的结果。该模型认为体系结构是由一组功能构件按层次组成,下层向上层提供服务,它可以看作是一种特殊的框架模型。
五、功能模型。
功能模型侧重于描述系统提供的服务和功能,即系统如何满足用户需求。它通常从用户的角度来定义系统的行为,并描述系统如何执行这些行为以满足特定的业务目标。
此外,从另一个角度来看,软件体系结构还可以通过“4+1”视图模型来描述,该模型从五个不同的视角包括逻辑视图、进程视图、物理视图、开发视图和场景视图来描述软件体系结构。每个视图都提供了对系统不同方面的理解和描述,有助于全面把握系统的结构和行为。
-
逻辑视图:主要支持系统的功能需求,即系统提供给最终用户的服务。它关注系统的功能分解和抽象,以及各个部分之间的交互和关系。
-
开发视图:也称模块视图,主要侧重于软件模块的组织和管理。它关注软件的内部结构和模块之间的关系,以及如何通过模块化和重用来提高开发效率和软件质量。
-
进程视图:侧重于系统的运行特性,主要关注一些非功能性的需求,如系统的性能和可用性。它强调并发性、分布性、系统集成性和容错能力等方面。
-
物理视图:主要考虑如何把软件映射到硬件上,它通常要考虑到系统性能、规模、可靠性等。它关注系统的物理部署和硬件资源的分配,以及系统之间的通信和交互。
-
场景视图:可以看作是那些重要系统活动的抽象,它使四个视图有机联系起来。它描述了系统在特定场景下的行为和交互,有助于理解系统的动态特性和用户需求。
综上所述,软件体系结构模型可以从多个角度进行划分和描述,每种模型都有其独特的侧重点和适用范围。在实际应用中,需要根据具体的需求和场景选择合适的模型来描述和分析软件系统。
-
-
尝试用自己的语言介绍Kruchten的“4十1”模型。
Kruchten的“4+1”模型是一种描述软件架构的框架,旨在通过不同的视角来全面理解和展示软件系统的结构。这个模型包括五个主要部分:逻辑视图、开发视图、过程视图、物理视图和场景视图(+1)。
-
逻辑视图:
-
主要描述系统的功能需求,即系统应该为用户提供哪些服务。
-
在逻辑视图中,系统被分解为一系列的功能抽象,这些抽象主要来自于问题域,表现为对象或对象类的形式。
-
通过面向对象的设计方法,如抽象、封装和继承,逻辑视图展示了系统的静态结构。
-
-
开发视图:
-
主要描述软件模块的组织与管理,即如何通过程序库或子系统来组织软件。
-
开发视图服务于软件编程人员,方便他们进行后续的设计与实现。
-
它通过系统输入输出关系的模型图和子系统图来描述,考虑了软件的内部需求,如开发的难易程度、重用的可能性等。
-
-
过程视图:
-
侧重于系统的运行特性,关注非功能性的需求,如性能、可用性、并发性、分布性等。
-
过程视图服务于系统集成人员,方便他们进行后续的性能测试。
-
它定义了逻辑视图中的各个类的具体操作是在哪一个线程中被执行的,从而展示了系统的动态行为。
-
-
物理视图:
-
主要描述硬件配置,即如何把软件映射到硬件上。
-
物理视图解决了系统的拓扑结构、系统安装、通信等问题,并考虑了系统性能、规模、可靠性等。
-
它与过程视图可以一起映射,共同描述系统的物理部署和硬件资源的分配。
-
-
场景视图(+1):
-
场景视图通过一组用例或用户故事,将上述四个视图有机地联系起来。
-
它描述了系统在不同场景下的行为和交互,从而展示了系统的多维度特性。
-
场景视图是“4+1”模型中的“+1”,它使得模型更加完整和全面。
-
总的来说,Kruchten的“4+1”模型通过五个不同的视角来全面描述软件系统的结构,每个视角都关注系统的不同方面。这种多维度的方法有助于设计者更全面地考虑系统的需求和挑战,从而设计出更加优秀的软件系统。同时,该模型也方便了不同利益相关者之间的沟通和理解,促进了项目的顺利进行。
-
-
为什么软件体系结构是必需的?软件体系结构在软件生命周期中的地位如何?
软件体系结构之所以是必需的,主要基于以下几个方面的原因:
-
作为系统开发中不同参与者进行交流和信息传播的媒介:软件体系结构为开发人员、测试人员、项目经理以及用户等提供了一个共同的语言和框架,使他们能够更有效地沟通和协作。通过明确的结构和规格说明,不同参与者可以更好地理解系统的需求和设计,从而协同工作以实现共同的目标。
-
代表了早期的设计决策成果:在软件开发过程中,早期的设计决策对后续工作起着至关重要的作用。软件体系结构作为这些决策的成果,为后续的详细设计、编码、测试等工作提供了指导和约束。它确保了整个开发过程的一致性和连贯性,减少了因设计变更而导致的额外成本和风险。
-
使系统拥有某些质量属性:软件体系结构决定了系统的质量属性,如性能、可扩展性、安全性、可维护性等。通过合理的架构设计,可以确保系统具备所需的属性,并能够在不同的环境和条件下稳定运行。
-
解释和管理变更:在软件开发过程中,变更是在整个开发周期中都会存在的。软件体系结构提供了一种有效的方法来管理和解释这些变更。通过明确的结构和模块划分,可以更容易地识别和理解变更的影响范围,从而采取相应的措施来应对。
-
预测系统的质量属性:软件体系结构不仅能使系统拥有某些质量属性,还能对系统的质量属性进行预测。在系统开发和集成之前,可以根据架构的评估进行合理的质量预测,以便及早发现潜在的问题并采取相应的解决措施。
在软件生命周期中,软件体系结构占据着举足轻重的地位。它是软件开发过程中的重要里程碑和决策点,对后续的开发工作起着至关重要的指导作用。具体来说,软件体系结构在软件生命周期中的地位可以体现在以下几个方面:
-
需求分析阶段:软件体系结构为需求分析提供了框架和约束,确保需求的一致性和完整性。通过明确的结构和规格说明,可以更好地理解和满足用户的需求。
-
设计阶段:软件体系结构是设计阶段的核心内容之一。它指导了系统的整体设计和模块划分,确保了系统的结构清晰、合理且易于维护。
-
编码阶段:在编码阶段,开发人员需要遵循软件体系结构的要求进行编码工作。这有助于确保代码的一致性和可维护性,并减少因设计不当而导致的错误和缺陷。
-
测试阶段:软件体系结构为测试工作提供了重要的参考依据。测试人员可以根据架构的特性和要求设计测试用例,以确保系统的质量和稳定性。
-
维护阶段:在软件维护阶段,软件体系结构仍然发挥着重要作用。它有助于维护人员更好地理解系统的结构和功能,从而更有效地进行维护和升级工作。
综上所述,软件体系结构是软件开发过程中不可或缺的一部分。它在软件生命周期中占据着重要地位,对系统的质量、稳定性和可维护性等方面起着至关重要的作用。
-
-
软件体系结构是软件系统的支架,除了用能够UML等相关的工具进行建模外,为什么还需要对体系结构进行抽象化?
软件体系结构作为软件系统的支架,在软件开发过程中起着至关重要的作用。除了使用UML等相关的工具进行建模外,对体系结构进行抽象化也是非常重要的,原因主要有以下几点:
一、提高系统的可理解性。
软件体系结构抽象化可以隐藏系统的复杂性和底层实现细节,使得开发者能够更专注于系统的高层次结构和行为。这种抽象化有助于简化系统的理解,使得开发者能够更容易地把握系统的整体框架和关键组件之间的关系。
二、增强系统的灵活性。
通过抽象化,软件体系结构能够更好地适应需求的变化。当系统需求发生变化时,只需要修改抽象层的相关部分,而不需要对整个系统进行大规模的修改。这种灵活性有助于降低系统的维护成本,提高系统的可扩展性和可维护性。
三、促进模块化设计。
抽象化有助于实现模块化设计,即将系统划分为一系列相对独立的模块。每个模块都负责特定的功能,并通过接口与其他模块进行交互。这种模块化设计有助于降低系统的复杂性,提高系统的可重用性和可测试性。
四、支持并发和分布式系统。
在并发和分布式系统中,抽象化可以隐藏底层通信和同步机制的复杂性,使得开发者能够更专注于业务逻辑的实现。通过提供统一的抽象接口,可以使得并发和分布式系统的开发更加简单和高效。
五、优化系统性能。
抽象化还可以帮助开发者更好地优化系统性能。通过对系统结构进行抽象化,可以更容易地识别出性能瓶颈和潜在的性能问题。同时,抽象化还可以为性能优化提供灵活的接口和工具,使得开发者能够更有效地进行性能调优工作。
综上所述,对软件体系结构进行抽象化是非常重要的。它不仅可以提高系统的可理解性和灵活性,还可以促进模块化设计、支持并发和分布式系统以及优化系统性能。因此,在软件开发过程中,应该充分重视软件体系结构的抽象化工作,以确保系统的质量和稳定性。