880 likes | 1.24k Views
软件体系结构 (Software Architecture). 一、软件体系结构起源和基本概念. 建筑的例子 —— 狗舍. 一个人搭建,需要 最小化建模 简单的过程 简单的工具. 建筑的例子 —— 住房. 一个团队高效和适时地建造,需要 仔细的建模 良好定义的过程 良好的工具. 建筑的例子 —— 摩天大楼. 从软件危机谈起 . 软件危机是指在计算机软件的开发和维护过程中遇到的一系列严重问题 1968 年国际软件工程会议提出,并被人们广泛认识到 软件危机的表现 软件成本日益增长 开发进度难以控制 软件质量差 软件维护困难. 软件危机的表现.
E N D
软件体系结构(Software Architecture) 一、软件体系结构起源和基本概念
建筑的例子——狗舍 • 一个人搭建,需要 • 最小化建模 • 简单的过程 • 简单的工具
建筑的例子——住房 • 一个团队高效和适时地建造,需要 • 仔细的建模 • 良好定义的过程 • 良好的工具
从软件危机谈起 • 软件危机是指在计算机软件的开发和维护过程中遇到的一系列严重问题 • 1968年国际软件工程会议提出,并被人们广泛认识到 • 软件危机的表现 • 软件成本日益增长 • 开发进度难以控制 • 软件质量差 • 软件维护困难
软件危机的表现 • 软件成本日益增长 • 20世纪50年代,软件成本在整个计算机系统成本中所占的比例为10%-20%。到20世纪60年代中期,软件成本在计算机系统中所占的比例已经增长到50%左右。 • 而且,该数字还在不断地递增,下面是一组来自美国空军计算机系统的数据:1955年,软件费用约占总费用的18%,1970年达到60%,1975年达到72%,1980年达到80%,1985年达到85%左右。
软件危机的表现 • 开发进度难以控制 • 由于软件是逻辑、智力产品,软件的开发需建立庞大的逻辑体系,这是与其他产品的生产不一样的。 • 在软件开发过程中,用户需求变化等各种意想不到的情况层出不穷,令软件开发过程很难保证按预定的计划实现,给项目计划和论证工作带来了很大的困难。 • 盲目增加软件开发人员并不能成比例地提高软件开发能力。相反,随着人员数量的增加,人员的组织、协调、通信、培训和管理等方面的问题将更为严重
软件危机的表现 • 软件质量差 • 软件项目即使能按预定日期完成,结果却不尽人意。1965年至1970年,美国范登堡基地发射火箭多次失败,绝大部分故障是由应用程序错误造成的。 • 在“软件作坊”里,由于缺乏工程化思想的指导,程序员几乎总是习惯性地以自己的想法去代替用户对软件的需求,软件设计带有随意性,很多功能只是程序员的“一厢情愿”而已,这是造成软件不能令人满意的重要因素。
软件危机的表现 • 软件维护困难 • 由于在软件设计和开发过程中,没有严格遵循软件开发标准,各种随意性很大,没有完整的真实反映系统状况的记录文档,给软件维护造成了巨大的困难。 • 特别是在软件使用过程中,原来的开发人员可能因各种原因已经离开原来的开发组织,使得软件几乎不可维护。 • 有资料表明,工业界为维护软件支付的费用占全部硬件和软件费用的40%-75%。
从软件危机谈起 • 软件危机的原因 • 用户需求不明确 • 缺乏正确的理论指导 • 软件规模越来越大 • 软件复杂度越来越高
软件危机的原因 • 用户需求不明确 • 在软件开发完成之前,用户不清楚软件的具体需求; • 用户对软件需求的描述不精确,可能有遗漏、有二义性、甚至有错误; • 在软件开发过程中,用户还提出修改软件功能、界面、支撑环境等方面的要求; • 开发人员对用户需求的理解与用户本来愿望有差异
软件危机的原因 • 缺乏正确的理论指导 • 缺乏有力的方法学和工具方面的支持。由于软件不同于大多数其他工业产品,其开发过程是复杂的逻辑思维过程,其产品极大程度地依赖于开发人员高度的智力投入。由于过分地依靠程序设计人员在软件开发过程中的技巧和创造性,加剧软件产品的个性化,也是发生软件危机的一个重要原因。
软件危机的原因 • 软件规模越来越大 • 随着软件应用范围的增广,软件规模愈来愈大。大型软件项目需要组织一定的人力共同完成,而多数管理人员缺乏开发大型软件系统的经验,而多数软件开发人员又缺乏管理方面的经验。各类人员的信息交流不及时、不准确、有时还会产生误解。 • 软件项目开发人员不能有效地、独立自主地处理大型软件的全部关系和各个分支,因此容易产生疏漏和错误。
软件危机的原因 • 软件复杂度越来越高 • 软件不仅仅是在规模上快速地发展扩大,而且其复杂性也急剧地增加。软件产品的特殊性和人类智力的局限性,导致人们无力处理“复杂问题”。 • 所谓“复杂问题”的概念是相对的,一旦人们采用先进的组织形式、开发方法和工具提高了软件开发效率和能力,新的、更大的、更复杂的问题又摆在人们的面前
从软件危机谈起 • 如何克服软件危机 • 人们面临的不光是技术问题,更重要的是管理问题。管理不善必然导致失败 。 • 要提高软件开发效率,提高软件产品质量,必须采用工程化的开发方法与工业化的生产技术。 • 在技术上,应该采用基于复用的软件生产技术;在管理上,应该采用多维的工程管理模式。 • 诞生了软件工程 • 用工程、科学和数学的原则和方法研制、维护计算机软件的有关技术及管理方法 • 方法:“如何做”的技术手段 • 工具:为方法提供的自动或者半自动的软件支撑环境 • 过程:将软件工程的方法和共计综合起来以达到合理、及时地进行计算机软件开发地目的 • 软件体系结构是软件工程学科的分支
软件复用 • 软件复用是指在两次或多次不同的软件开发过程中重复使用相同或者相近软件元素的过程 • 软件元素包括程序代码、测试用例、设计文档、设计过程、需求分析文档甚至领域知识
软件复用 • 软件系统极少是全新的 • 它们通常是“主旋律的变奏” • 建造“每类一个”的系统过于昂贵 • 在任何工程领域都是如此 • 在软件工程领域,尤其如此 • 针对“新”问题,有大量现成的解决方案 • OTS (off-the-shelf)系统 • 可能只提供部分解决方案 • 代码行不再是基本的软件构造单元 • 模块/构件成为开发、功能、演化/维护和复用的单元 • 类似于土木工程
复用的好处 • 减少开发时间 • 潜在的“即插即用” • 增加可靠性 • 通过测试 • 多重使用 • 改善质量 • 可移植性 • 互操作性 • 快速重新配置 • 用户编程 • 通过构件组装
软件复用的经济环境 • 为复用而设计需要更高的前期投资 • 开发成本增加10%至50% • 维护可复用资产库的附加成本 • 可复用构件的维护 • 当一个构件被复用时,这些成本将得到补偿 • 成本节省 2倍 至 20倍 • 需要远见 ► 管理层的支持是必须的 • OTS复用伴随着一定的风险 • 缺乏信任 • 被复用软件未知的可靠性 • 被复用软件不充分的理解 ► 成本和预算超支的可能
复用的技术困难 • OTS系统没有包含可清晰辨识的构件 • OTS构件粒度过大或过小 • OTS构件没有正好提供所要求的功能集 • OTS构件的规约和集成不可预见地复杂 • 复用一个构件的附加成本可能比重新开发更高 • 定位/选取 • 理解 • 提取 • 评估/适应性改造 • 集成
软件复用的实情[Krueger 1992] • 复用技术要想有效,必须缩短系统的初始概念和最终可执行实现之间的距离 • 复用技术要想有效,必须使复用制品的难度低于重新构造的难度 • 选择一个制品复用,必须知道它做什么 • 要想有效地复用一个软件制品,必须能够以比构造它更短的时间内发现它
软件复用的方法(1) • 高级语言 • 复用语言命令模式 • 设计和代码挖掘 • 需要巨大的时间/精力投入 • 收益不可预知 • 源代码构件 • 专为复用开发的构件 • 成功用于小的、易于理解的领域 • 通用构件库倾向于不实用 • 软件模式 • 使用抽象的算法和数据结构,而非源代码 • 在高于代码的抽象层次上形式化规约 • 可能因为太复杂而难以定位、理解和使用
软件复用的方法(2) • 应用系统生成器 • 类似于程序语言编译器,但适用于较窄的领域 • 应用于非常高层、专用的抽象 • 不适用于广泛的应用 • 甚高级语言和转换系统 • 使用“可执行的规约语言” • 典型的数学抽象,例如,集合论 • 更通用的应用,但不像生成器功能强大 • (人工引导)从规约到实现的转换 • 软件体系结构
软件开发当前所处的位置 • 软件系统天生是复杂的 • 某些复杂性是可控的 • 提高为开发人员提供的抽象层次 • 努力同开发人员的思维模式相匹配 • 针对上述问题,出现的特定技术 • 描述软件系统的符号体系 • 从可复用的、粗粒度的构造块搭建系统的技术和工具 • 关注于整体系统结构 还有很长的路要走!
软件体系结构的焦点和范围 • 软件体系结构是一个软件系统的设计图(blueprint) • 解决复杂性问题 • 提高复用和构件市场的潜力 • 包含形式化方法 • 两个主要焦点 • 系统结构 • 需求和实现之间的对应 ► 构件 + 组装规则 + 行为规则 • 理解系统级关注的框架 • 全局流动率,通讯模式,执行控制机构,可升级性,系统演化路径,容量,吞吐量,一致性,构件兼容性,等
软件体系结构的发展史 以汇编语言进行小规模应用程序开发为特征 出现了程序结构设计主题,以控制流图和数据流图构成软件结构为特征 萌芽阶段 出现了从不同侧面描述系统的结构模型,以UML为典型代表。 初期阶段 以描述系统的高层抽象结构为中心,不关心具体的建模细节,划分了体系结构模型与传统软件结构的界限,该阶段以Kruchten提出的“4+1”模型为标志 高级阶段 “无体系结构”设计阶段
软件体系结构的发展史 Perry和Wolf认为 未来的年代是研究软件体系结构的时代
概念起源(1) • 对软件体系结构的研究可以追溯到20世纪60年代,当时主要是对软件结构的研究。 • 1969年,Brooks提出“概念结构” • In programming, the term architecture was first used to mean a description of a computer system that applied equally to more than one actual system • 体系结构和实现被仔细区分开来 • Architecture tells what happens • Implementation tells how it is made to happen • 体系结构作为“一组系统的公共描述”的想法被保持下来,并成为概念的核心
概念起源(2) • 1968年,Edsger Dijkstra提出“层次结构”的想法 • 当时,软件体系结构的研究主要是针对软件结构,即软件如何划分和结构化,而不是简单地编程以产生正确的结果 • 以操作系统为例,Dijkstra首次提出“层次结构”的想法,程序被归结到不同的层次,只有相邻层次的程序可以互相访问 • 通过上述系统组织所展现出的概念完整性,可以减轻开发和维护的负担
概念起源(3) • 1970年代初,David Parnas提出一系列重要的思想 • 1972年,信息隐蔽 (information-hiding) • 1974年,软件结构 (software structures) • 1975年,程序家族 (program families) • 一个程序家族是一组程序(并非所有这些程序已经或将被构造),把它们作为一组看待是有益或有用的 • 理论上,一个程序家族可以通过遍历一个决策树进行枚举,树的叶节点代表装配好的、可执行的系统 • 这个概念支持从现存的家族成员导出新成员的想法,过程是在决策树上回溯,直到达到一个公共的节点(决策点),然后沿着新的路径导出希望的成员 • 这个概念还支持从一个公共决策点导出多个家族成员,以此解释这些成员之间的相似和不同
概念起源(4) • 在决策树上越靠近根节点的部分,越代表了对程序家族成员保持稳定的那些早期设计决策 • 在这样的上下文中,早期决策代表特定的体系结构 • 后期决策(靠近叶节点)代表琐细、易变的决策,例如编译时刻、甚至加载时刻的常量 • 程序家族概念对软件体系结构的意义在于,软件体系结构包含了决策树根部或靠近根部的那些决策 • 1976年,Frank DeRemer和Hans Kron提出了模块连接语言MIL75 • “Programming-in-large versus programming-in-small”,[IEEE Trans. on SE, June 1976]
概念起源(5) • 以编译器为例,在1970~1980年代,编译器设计发展成为标准的程序 • 对所有编译器公共的决策被复用,例如,词法分析器、语法分析器、语义树、属性文法、目标代码生成器、优化器,等 • 许多其他领域的成员之间,呈现出 • 公共结构,互连策略,功能到构件的分配,构件接口,整体合理化基础 • 软件体系结构的工作可被看作一种事后努力 • 为可复用的家族范围的设计信息提供结构化的仓库 • 试图整理程序家族各成员之间的共性,从而家族成员内在的高层设计决策不需要重复地发明、验证和描述
概念起源(6) • 从1980年代初期开始,人们在软件设计方面的注意力逐渐集中到面向对象方法上。经过二十多年的研究和实践,人们形成了这样一个共识: • 对象并不是解决所有设计问题的灵丹妙药,软件工程必须超越面向对象方法,形成以体系结构为中心的新方法 • 面向对象方法在软件体系结构设计中存在的误区 • 基本特征:模块化、封装、继承、多态等 • OO程序员更多关注的是低层次,而不是高层次的抽象 • 对象(类)的粒度过小:趋向于实现层次 • 对象(类)之间的关系类型过于一般化:依赖(dependency),泛化(generalization),关联(association)
发展现状(1) • 真正现在意义上的软件体系结构的研究始于, • Dewayne Perry和Alexander Wolf [PW1992], and • David Garlan和Mary Shaw [GS1993]的奠基性工作, and • 其他人对体系结构风格的分类和评价 [KBA+1994], and • 特定领域软件体系结构 (DSSAs)的研究和应用 [DSSA1992] • 应用现状 • 体系结构的设计是建立在直觉和经验、而非坚实的工程原则之上的 • 体系结构的描述是非形式化的和随意的,经常采用框线图(box-and-line diagram)加文字注释的方法
发展现状(2) • 应用后果 • 体系结构设计只是被开发人员含糊地理解 • 难以对体系结构设计作出一致性或完整性的分析 • 随着系统的演化,难以保持同系统原有体系结构的一致,并且 • 难以开发有效的工具,辅助人们进行体系结构的设计、性质分析和验证
发展现状(3) • 在“软件复用的展望和策略” [DoD1992]报告中,美国国防部强调了“以体系结构为中心的复用”在整个软件生存周期中,对于软件开发和支持的重要性。 • 以下是一些同体系结构相关的研究项目, • STARS, DOD • CARDS, DOD • PRISM, DOD • RAPIDE , Stanford Uni. • C2 style and ADL, California Uni. • Able (Architecture Based Languages and Environments), CMU • ACME Architecture Interchange Language, CMU • Vitruvius, CMU
发展现状(4) • 鉴于是否有一个稳定的软件体系结构,对软件的质量和成本影响很大,因此如何获得一个良好的体系结构就成为当今软件界研究的重点。 • 当前软件体系结构研究和实践中,一些最活跃的领域包括: • 各种体系结构风格的汇编和总结 • 体系结构描述语言 • 体系结构的形式化基础 • 体系结构分析技术 • 基于体系结构的开发方法 • 体系结构恢复和再工程 • 支持体系结构设计的工具和环境 • 特定领域的软件体系结构(DSSA) • ……
软件体系结构的定义(1) • Perry and Wolf, 1992 • 软件体系结构=(元素,形态,基本理论) • 软件体系结构是一组具有特定形式的设计元素。这里的设计元素被分为三类:处理元素 (processing elements)、数据元素 (data elements)和连接元素(connection elements) • Kruchten, 1994 • 软件体系结构涉及软件高层结构的设计和实现,通过组装一定数量的具有良好形态的元素,以满足主要的功能和性能需求,例如,可扩展性和可用性 • 涉及抽象、分解/组装、风格/审美
软件体系结构的定义(2) • Shaw and Garlan, 1996 • 一个软件系统的体系结构定义了组成系统的计算构件和构件之间相互作用的关系 • 软件体系结构层次的设计主要包括以下方面: • 组成系统的构件描述 • 构件之间的交互 • 指导构件交互的模式,以及 • 施加在模式上的约束 • Bass, Clements, and Kazman, 1997 • 软件体系结构是一个系统的结构,包括软件构件、构件的外部可见属性、以及构件关系 • 这里,“外部可见”属性指的是其他构件可以对该构件所做的假定,比如它提供的服务、性能特性、错误处理、共享资源的使用等
软件体系结构的定义(3) • Booch, Rumbaugh, and Jacobson, 1999 • 软件体系结构是一组关于下述问题的重要决定, • 软件系统的组织 • 构成系统的结构化元素和它们接口的选择 • 这些模型元素之间的协作所描述的行为 • 这些结构化和行为元素的组装,以形成更大的子系统 • 指导这种组织(静态和动态元素,以及它们的接口、协作和组装)的体系结构风格 • 软件体系结构不仅关注结构和行为,也关注使用、功能、性能、弹性、复用、可理解性、经济和技术约束与折衷、审美考虑
软件体系结构的定义(4) vocabulary functionality system assembly configuration management Design view Implementation view Use case view behavior Process view Deployment view performance scalability throughput system topology distribution delivery installation 采用UML进行软件体系结构建模
软件体系结构的定义(5) A2 B1 A1 B2 A3 • 一个软件系统的体系结构定义了组成系统的 • 构件(components), • 连接件(connectors),和 • 它们之间的匹配 • 这里,构件用于实施计算和保存状态,连接件用于表达构件之间的关系,构件和连接件之间的匹配表示了系统的拓扑结构。
体系结构的关键概念 • 三类基本的“积木(building blocks)” • 构件(components) • 连接件(connectors) • 配置(configurations) • 理想地,“积木”应该独立定义 • 支持在不同上下文环境中的复用 • 支持没有被当初的开发者预料到的互连
构件 • 构件是计算或数据储存的单元 • Perry & Wolf定义中的处理元素和数据元素 • 构件是计算和状态的场所 • 客户(clients) • 服务器(servers) • 数据库(databases) • 过滤器(filters) • 层次(layers) • 抽象数据类型(ADTs) • 构件可以是简单的或复合的 • 复合构件描述了一个(子)系统
连接件 • 连接件是对以下内容进行建模的体系结构元素 • 构件之间的交互 • 指导这些交互的规则 • 简单交互 • 过程调用 • 共享变量访问 • 复杂和语义丰富的交互 • 客户/服务器协议 • 数据库访问协议 • 异步事件广播 • 管道数据流
连接件 • 传统方法中,构件之间的连接关系通常并不独立存在,而是从属于构件,且表达能力较弱 • 由于以下原因,表达构件之间关系的连接件应该从中分离出来,作为同构件平等的第一类实体: • 连接件可能要表达构件之间相当复杂的关系语义,需要详细的定义和复杂的规约 • 复杂连接件的定义应当局部化,而不是分散定义在多个构件中,以保证系统具有良好的结构 • 构件之间的关系并非是固定不变的,有可能随着系统的运行需要动态改变,这种改变应封装在连接件中 • 连接件和构件一样,都应该是独立的和各有分工的。构件应该只定义它的能力(包括功能和非功能两个方面);连接件应该规定构件之间的交互 • 系统开发时常常复用已有的连接件,例如过滤器、客户-服务器协议、数据库访问协议等
配置/拓扑 • 体系结构的配置或拓扑是构件和连接件的连接图(connected graph),描述了系统结构 • 适当的连接 • 并发和分布特性 • 符合设计启发式规则和风格规则 • 复合构件本身就是配置
构件模型及实现 • 构件的定义 • 构件是指语义完整、语法正确和有可复用价值的单位软件,是软件复用过程中可以明确辨识的元素;结构上,它是语义描述、通讯接口和实现代码的复合体。
构件模型及实现 • 构件模型的三个主要流派 • OMG(Object Management Group,对象管理集团)的CORBA(Common Object Request Broker Architecture,通用对象请求代理结构) • Sun的EJB(Enterprise Java Bean) • Microsoft的DCOM(Distributed Component Object Model,分布式构件对象模型)。
构件模型及实现 • 青鸟构件模型