版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第2章软件体系结构2.1软件体系结构的产生与发展2.2软件体系结构建模2.3基于体系结构的描述2.4基于体系结构的软件设计2.5小结
2.1软件体系结构的产生与发展
20世纪60年代的软件危机使得人们开始重视软件工程的研究。起初,人们把软件设计的重点放在数据结构和算法的选择上,随着软件系统规模越来越大、越来越复杂,整个系统的结构和规格说明显得越来越重要。软件危机的程度日益加剧,现有的软件工程方法对此显得力不从心。对于大规模的复杂软件系统来说,对总体的系统结构设计和规格说明的选择比起对计算的算法和数据结构的选择已经变得明显重要很多。在此背景下,人们认识到软件体系结构的重要性,并认为对软件体系结构的系统、深入的研究将会成为提高软件生产率和解决软件维护问题的新的最有希望的途径。自从软件系统首次被分成许多模块,模块之间有相互作用,组合起来有整体的属性,软件系统就具有了体系结构。好的开发者常常会使用一些体系结构模式作为软件系统结构的设计策略,但他们并没有规范地、明确地表达出来,这样就无法将他们的知识与别人交流。软件体系结构是设计抽象的进一步发展,满足了更好地理解软件系统,更方便地开发更大、更复杂的软件系统的需要。
事实上,软件总是有体系结构的,不存在没有体系结构的软件。体系结构(Architecture)一词在英文里就是“建筑”的意思。把软件比作一座楼房,从整体上讲,是因为它有基础、主体和装饰,即操作系统之上的基础设施软件、实现计算逻辑的主体应用程序、方便使用的用户界面程序。从细节上来看每一个程序也是有结构的,早期的结构化程序就是以语句组成模块,模块的聚集和嵌套形成层层调用的程序结构,也就是它的体系结构。结构化程序的程序(表达)结构和(计算的)逻辑结构的一致性及自顶向下的开发方法自然而然地形成了体系结构。由于在结构化程序设计时代程序的规模不大,通过强调结构化程序设计方法学,自顶向下、逐步求精,并注意模块的耦合性就可以得到相对良好的结构,所以并未去特别研究软件体系结构。我们可以作个简单的比喻,结构化程序设计时代是以砖、瓦、灰、沙、石、预制梁、柱、屋面板盖平房和小楼,而面向对象时代以整面墙、整间房、一层楼梯的预制件盖高楼大厦。构件怎样搭配才合理?体系结构怎样构造容易?重要构件有了更改后,如何保证整栋高楼不倒?每种应用领域需要什么构件(医院、工厂、旅馆)?有哪些实用、美观、强度高、造价合理的构件骨架使建造出来的建筑(即体系结构)更能满足用户的需求?如同土木工程进入到现代建筑学一样,软件也从传统的软件工程进入到现代面向对象的软件工程,研究整个软件系统的体系结构,寻求建构最快、成本最低、质量最好的构造过程。软件体系结构虽脱胎于软件工程,但其形成同时借鉴了计算机体系结构和网络体系结构中很多宝贵的思想和方法。最近几年软件体系结构研究已完全独立于软件工程的研究,成为计算机科学的一个最新的研究方向和独立的学科分支。软件体系结构研究的主要内容涉及软件体系结构描述、软件体系结构风格、软件体系结构评价和软件体系结构的形式化方法等。解决好软件的重用、质量和维护问题,是研究软件体系结构的根本目的。2.1.1软件体系结构的定义
虽然软件体系结构已经在软件工程领域中有着广泛的应用,但迄今为止还没有一个被大家所公认的定义。许多专家学者从不同角度和不同侧面对软件体系结构进行了刻画,较为典型的定义有:
(1) DewaynePerry和AlexWolf曾这样定义:软件体系结构是具有一定形式的结构化元素,即构件的集合,包括处理构件、数据构件和连接构件。处理构件负责对数据进行加工,数据构件是被加工的信息,连接构件把体系结构的不同部分组合连接起来。这一定义注重区分处理构件、数据构件和连接构件,该特点在其他的定义和方法中基本上得到了保持。
(2) MaryShaw和DavidGarlan认为软件体系结构是软件设计过程中的一个层次,这一层次超越计算过程中的算法设计和数据结构设计。体系结构问题包括总体组织和全局控制,通信协议,同步与数据存取,给设计元素分配特定功能,设计元素的组织、规模和性能,在各设计方案间进行选择等。软件体系结构处理算法与数据结构之上关于整体系统结构设计和描述方面的一些问题,包括全局组织和全局控制结构,关于通信、同步与数据存取的协议,设计构件功能定义,物理分布与合成,设计方案的选择、评估与实现等。
(3) Kruchten指出,软件体系结构有四个角度,它们从不同方面对系统进行描述:概念角度描述系统的主要构件及它们之间的关系;模块角度包含功能分解与层次结构;运行角度描述了一个系统的动态结构;代码角度描述了各种代码和库函数在开发环境中的组织。
(4) HayesRoth则认为软件体系结构是一个抽象的系统规范,主要包括用其行为来描述的功能构件和构件之间的相互连接、接口和关系。
(5) DavidGarlan和DewnePerry于1995年在IEEE软件工程学报上又发表了如下定义:软件体系结构是一个程序/系统各构件的结构及其相互关系,以及进行设计的原则和随时间进化的指导方针。
(6) BarryBoehm和他的学生提出,一个软件体系结构包括一个软件和系统构件、互联及约束的集合、一个系统需求说明的集合以及一个基本原理,用以说明这一构件、互联和约束能够满足系统需求。
(7)1997年,Bass、Ctements和Kazman在《使用软件体系结构》一书中给出如下定义:一个程序或计算机系统的软件体系结构包括一个或一组软件构件、软件构件外部的可见特性及其相互关系。其中,“软件外部的可见特性”是指软件构件提供的服务、性能、特性、错误处理、共享资源使用等。综上所述,软件体系结构为软件系统提供了一个结构、行为和属性的高级抽象,由构成系统的元素的描述、这些元素的相互作用、指导元素集成的模式以及这些模式的约束组成。软件体系结构不仅指定了系统的组织结构和拓扑结构,而且显示了系统需求和构成元素之间的对应关系,提供了一些设计决策的基本原理。2.1.2软件体系结构的发展史
在软件系统的规模迅速增大的同时,软件开发方法也经历了一系列的变革。在此过程中,软件体系结构也由最初模糊的概念发展成为渐趋成熟的理论和技术。
20世纪70年代以前,尤其是在以ALGOL68为代表的高级语言出现以前,软件开发基本上都是汇编程序设计,此阶段系统规模较小,很少明确考虑系统结构,一般不存在系统建模工作。70年代中后期,由于结构化开发方法的出现与广泛应用,软件开发中出现了概要设计与详细设计,而且主要任务是数据流设计与控制流设计,因此,此时软件结构已作为一个明确的概念出现在系统的开发中。
20世纪80年代初到90年代中期,是面向对象开发方法兴起与成熟的阶段。由于对象是数据与基于数据之上操作的封装,因而在面向对象开发方法下,数据流设计与控制流设计则统一为对象建模。同时,面向对象方法还提出了一些其他的结构视图,如在OMT(ObjectModelingTechnology,对象建模技术)方法中提出了功能视图、对象视图与动态视图(包括状态图和事件追踪图);在Booch方法中则提出了类视图、对象视图、状态迁移图、交互作用图、模块图、进程图;而1997年出现的统一建模语言(UML)则用功能模型(用例视图)、静态模型(包括类图、对象图、构件图、包图)、动态模型(协作图、顺序图、状态图和活动图)、配置模型(配置图)描述应用系统的结构。
20世纪90年代以后则进入基于构件的软件开发阶段,该阶段以过程为中心,强调软件开发采用构件化技术和体系结构技术,要求开发出的软件具备很强的自适应性、互操作性、可扩展性和可重用性。此阶段中,软件体系结构已经作为一个明确的文档和中间产品存在于软件开发过程中;同时,软件体系结构作为一门学科逐渐得到人们的重视,并成为软件工程领域的研究热点。因而Perry和Wolf认为:未来的年代将是研究软件体系结构的时代。
纵观软件体系结构技术的发展过程,从最初的“无体系结构”设计到现行的基于体系结构的软件开发,可以认为经历了四个阶段:
(1)“无体系结构”设计阶段,以汇编语言进行小规模应用程序开发为特征。
(2)萌芽阶段,出现了程序结构设计主题,以控制流图和数据流图构成软件结构为特征。
(3)初期阶段,出现了从不同侧面描述系统的结构模型,以UML为典型代表。
(4)高级阶段,以描述系统的高层抽象结构为中心,不关心具体的建模细节,划分了体系结构模型与传统软件结构的界限,该阶段以Kruchten提出的“4+1”模型为标志。由于概念尚不统一,描述规范也不能达成一致认识,在软件开发实践中软件体系结构尚不能发挥重要作用。2.1.3软件体系结构的研究现状
(1)形成研究热点,仍处于非形式化水平。自20世纪90年代后期以来,软件体系结构的研究成为一个热点。广大软件工作者已经认识到软件体系结构研究的重大意义和它对软件系统设计开发的重要性,开展了很多研究和实践工作。
从软件体系结构研究的现状来看,当前的研究和对软件体系结构的描述,在很大程度上来说还停留在非形式化的基础上。软件构架师仍然缺乏必要的工具,这种工具应该是显式描述、有独立性的形式化工具。在目前通用的软件开发方法中,对软件体系结构的描述通常采用非形式化的图和文本,不能描述存在于构件之间的接口,更不能描述不同的系统组成成分间的组合关系。这种描述方法难以被开发人员理解,不能用来分析其一致性和完整性等特性。
当一个软件系统中的构件几乎以一种非形式化的方法描述时,系统的重用性也会受到影响,在设计一个系统结构过程中的努力很难移植到另一个系统中去。对系统构件和连接关系的结构化假设没有得到显式的、形式化的描述时,把这样的系统构件移植到另一个系统中去将是有风险的,甚至是不可能的。
(2)软件体系结构的形式化方法研究。软件体系结构研究如果仅仅停留在非形式化的框图阶段,已经难以适应进一步发展的需要。为支持基于体系结构的开发,需要有形式化建模符号、体系结构说明的分析与开发工具。从软件体系结构研究的现状来看,在这一领域近来已经有不少进展,其中比较有代表性的是美国卡耐基梅隆大学(CarnegieMellonUniversity)的RobertJ. Allen于1997年提出的Wright系统。Wright是一种结构描述语言,该语言基于一种形式化的、抽象的系统模型,为描述和分析软件体系结构和结构化方法提供了一种实用的工具。Wright主要侧重于描述系统的软件构件和连接的结构、配置和方法,它使用显式的、独立的连接模型来作为交互的方式,这使得该系统可以用逻辑谓词符号系统,而不依赖特定的系统实例来描述系统的抽象行为。该系统还可以通过一组静态检查来判断系统结构规格说明的一致性和完整性。从这些特性的分析来说,Wright系统的确适用于对大型系统的描述和分析。
(3)软件体系结构的建模研究。研究软件体系结构的首要问题是如何表示软件体系结构,即如何对软件体系结构建模。根据建模的侧重点的不同,可以将软件体系结构的模型分为5种:结构模型、框架模型、动态模型、过程模型和功能模型。在这5种模型中,最常用的是结构模型和动态模型。这一问题将在后续章节中进一步详细阐述。
(4)发展基于体系结构的软件开发模型。软件开发模型是跨越整个软件生存周期的系统开发、运行、维护所实施的全部工作和任务的结构框架,给出了软件开发活动各阶段之间的关系。目前,常见的软件开发模型大致可分为以下三种类型:
①以软件需求完全确定为前提的瀑布模型。
②在软件开发初始阶段只能提供基本需求时采用的渐进式开发模型,如螺旋模型等。
③以形式化开发方法为基础的变换模型。所有开发方法都是要解决需求与实现之间的差距,但是,这三种类型的软件开发模型都存在这样或那样的缺陷,不能很好地支持基于软件体系结构的开发过程。因此,研究人员在发展基于体系结构的软件开发模型方面做了一定的工作。
(5)软件产品线体系结构的研究。软件体系结构的开发是大型软件系统开发的关键环节。体系结构在软件生产线的开发中起着至关重要的作用。在这种开发生产中,基于同一个软件体系结构,可以创建具有不同功能的多个系统。在软件产品族之间共享体系结构和一组可重用的构件,可以增加软件工程和降低开发、维护成本。一个产品线代表着一组具有公共的系统需求集的软件系统,它们都是根据基本的用户需求对标准的产品线构架进行定制,将可重用构件与系统独有的部分集成而得到的。采用软件生产线模式进行软件生产,将产生巨型编程企业,但目前生产的软件产品族大部分是处于同一领域的。2.1.4软件体系结构的影响
软件体系结构贯穿于软件研发的整个生命周期,具有重要的影响。这主要从以下三个方面来进行考察:
(1)相关人员之间的交流。软件体系结构是一种常见的对系统的抽象。代码级别的系统抽象仅仅可以成为程序员的交流工具,而包括程序员在内的绝大多数系统的利益相关人员都借助软件体系结构来进行彼此理解、协商、达成共识或者相互沟通。
(2)系统设计的前期决策。软件体系结构是我们所开发的软件系统最早期设计决策的体现,而这些早期决策对软件系统的后续开发、部署和维护都有相当重要的影响,这也是能够对所开发系统进行分析的最早时间点。
(3)可传递的系统级抽象。软件体系结构是关于系统构造以及系统各个元素工作机制的相对较小、却又能够突出反映问题的模型。由于软件系统具有的一些共通特性,这种模型可以在多个系统之间传递,特别是可以应用到具有相似质量属性和功能需求的系统中,并能够促进大规模软件的系统级复用。2.1.5软件体系结构的发展方向
当前,体系结构仍是一个非常新的研究领域,其概念还相当模糊。但软件体系结构作为软件工程领域中的一个组成部分,已经取得了长足的发展,受到大多数软件系统设计和研究人员的重视。
(1)各种体系结构描述语言之间的信息互换。现有的体系结构描述语言大多是与领域相关的,所以不利于对不同领域体系结构的说明,但这些针对不同领域的体系结构描述语言在某些方面又大同小异,造成资源的冗余。其实,大多数体系结构描述语言具有一系列的共同概念,如何用一种公共形式把各种语言综合起来,从而能够交换各种体系结构描述信息,将是今后软件体系结构研究和实践的重点之一。
(2)设计工具和环境。软件体系结构设计既然作为软件工程的一部分,它的计算机辅助实现手段是相当重要的。我们应当开发出一些软件工具来实现体系结构的描述和分析,还应开发转换工具以实现阶段成果的自动转换,例如把需求规格说明自动转换为构件等。目前关于这方面的研究成果很少,特别是可以应用到实际项目开发中的工具和环境就更少。
(3)体系结构再工程。当今软件系统的规模变得越来越大,结构也越来越复杂,同时从头开始构建的大系统数量在急剧地减少,因而很多遗留系统正在被逐步地利用。从遗留系统软件代码和系统中抽取结构信息,经过描述、统一、抽象、一般化与实例化等处理,可总结出系统的体系结构。在这种情况下,软件再工程变得越来越重要,因为它提供了一条把遗留系统转换为可进化系统的现实可行的途径,是一种可以改进人们对软件的理解和改进软件本身的活动。这类研究的目的是为一些特定的应用领域的软件系统提供一些体系结构框架,如控制系统、移动机器人和用户接口界面等,通过这些框架可以很方便地构造一个新的软件系统。 2.2软件体系结构建模
研究软件体系结构的首要问题是如何表示软件体系结构,即如何对软件体系结构建模。根据建模的侧重点的不同,可以将软件体系结构的模型分为5种:结构模型、框架模型、动态模型、过程模型和功能模型。在这5种模型中,最常用的是结构模型和动态模型。
(1)结构模型。结构模型是一个最直观、最普遍的建模方法。这种方法以体系结构的构件、连接件和其他概念来刻画结构,并力图通过结构来反映系统的重要语义内容,包括系统的配置、约束、隐含的假设条件、风格、性质等。研究结构模型的核心是体系结构描述语言。
(2)框架模型。框架模型与结构模型类似,但它不太侧重描述结构的细节而更侧重于整体的结构。框架模型主要以一些特殊的问题为目标建立只针对和适应该问题的结构。
(3)动态模型。动态模型是对结构或框架模型的补充,研究系统的“大颗粒”的行为性质。例如,描述系统的重新配置或演化。其动态可能指系统总体结构的配置、建立或拆除通信通道或计算的过程。这类系统常是激励型的。
(4)过程模型。过程模型研究构造系统的步骤和过程,因而其结构是遵循某些过程脚本的结果。
(5)功能模型。功能模型认为体系结构由一组功能构件按层次组成,下层为上层提供服务。它可以看做是一种特殊的框架模型。2.2.1“4+1”视图模型
上面提到的5种模型各有所长,也许将5种模型有机地统一在一起,形成一个完整的模型来刻画软件体系结构更合适。例如,Kruchten在1995年提出了一个“4+1”的视角模型。“4+1”模型从5个不同的视角(包括逻辑视角、过程视角、物理视角、开发视角和场景视角)来描述软件体系结构,每一个视角只关心系统的一个侧面,5个视角结合在一起才能够反映系统的软件体系结构的全部内容。“4+1”模型如图2.1所示。图2.1“4+1”模型
1.逻辑视图
逻辑视图(logicview)主要支持系统的功能需求,即系统提供给最终用户的服务。在逻辑视图中,系统分解成一系列的功能抽象,这些抽象主要来自问题领域。这种分解不但可以用来进行功能分析,而且可用作标识整个系统的各个不同部分的通用机制和设计元素。在面向对象技术中,通过抽象、封装和继承,可以用对象模型来代表逻辑视图,用类图(classdiagram)来描述逻辑视图。我们可以从Booch标记法中导出逻辑视图的标记法,从体系结构级的范畴来考虑这些符号,用RationalRose进行体系结构设计。图2.2是逻辑视图中使用的符号集合。图2.2逻辑视图中使用的符号集合类图用于表示类的存在以及类与类之间的关系,是从系统构成的角度来描述正在开发的系统的。一个类的存在不是孤立的,类与类之间以不同方式互相合作,共同完成某些系统功能。关联关系表示两个类之间存在着某种语义上的联系,其真正含义要由附加在横线上的一个短语予以说明。在表示包含关系的图符中,带有实心圆的一端表示整体,相反的一端表示部分;在表示使用关系的图符中,带有空心圆的一端连接在请求服务的类,相反的一端连接在提供服务的类;在表示继承关系的图符中,箭头由子类指向基类。逻辑视图中使用的风格为面向对象的风格,逻辑视图设计中要注意的主要问题是要保持一个单一的、内聚的对象模型并使其贯穿于整个系统。例如,图2.3是某通信系统体系结构(ACS)中的主要类。
ACS的功能是在终端之间建立连接,这种终端可以是电话机、主干线、专用线路、特殊电话线、数据线或ISDN线路等,不同线路由不同的线路接口卡来支持。线路控制器对象的作用是译码并把所有符号加入到线路接口卡中;终端对象的作用是保持终端的状态,代表本条路线的利益参与协商服务;会话对象代表一组参与会话的终端,使用转换服务(目录、逻辑地址映射到物理地址、路由等)和连接服务,在终端之间建立语音路径。图2.3通信系统体系结构逻辑视图对于更大规模的系统来说,体系结构级中可能包含数十甚至数百个类。例如,图2.4是一个空中交通管制系统的顶级类图,该图包含了8组类。图2.4空中交通管制系统的顶级类图
2.开发视图
开发视图(developmentview)也称模块视图(moduleview),主要侧重于软件模块的组织和管理。软件可通过程序库或子系统进行组织,这样,对于一个软件系统,就可以由不同的人进行开发。开发视图要考虑软件内部的需求,如软件开发的容易性、软件重用、软件的通用性,还要充分考虑由于具体开发工具的不同而带来的局限性。
开发视图通过系统输入输出关系的模型图和子系统图来描述。可以在确定了软件包含的所有元素之后描述完整的开发角度,也可以在确定每个元素之前,列出开发视图原则。
与逻辑视图一样,我们可以使用Booch标记法中的某些符号来表示开发视图,如图2.5所示。图2.5开发视图中使用的标记符号在开发视图中,最好采用4~6层子系统,而且每个子系统只能与同层或更低层的子系统通信,这样可以使每个层次的接口既完备又精练,避免了各个模块之间很复杂的依赖关系。而且,设计时要充分考虑,对于各个层次,层次越低,通用性越强,这样可以保证应用程序的需求发生改变时,所做的改动最小。开发视图所用的风格通常是层次结构风格。例如,图2.6表示的是空中交通管制系统的5层结构图。
图2.6是图2.4的开发视图。第1层和第2层组成了一个领域无关的分布式基础设施,贯穿于整个产品线中,并且与硬件平台、操作系统或数据库管理系统等无关。第3层增加了空中交通管制系统的框架,以形成一个领域特定的软件体系结构。第4层使用该框架建立一个功能平台。第5层则依赖于具体客户和产品,包括了大部分用户接口以及外部系统接口。图2.6空中交通管制系统的5层结构
3.进程视图
进程视图(processview)侧重于系统的运行特性,主要关注一些非功能性的需求,例如系统的性能和可用性,进程视图强调并发性、分布性、系统集成性和容错能力。它也定义了逻辑视图中的各个类的操作具体是在哪一个线程(thread)中被执行的。
进程视图可以描述成多层抽象,每个级别分别关注不同的方面。在最高层抽象中,进程结构可以看做是构成一个执行单元的一组任务,也可看成一系列独立的、通过逻辑网络相互通信的程序,它们是分布的,通过总线或局域网、广域网等硬件资源连接起来。通过进程视图可以从进程测量一个目标系统最终的执行情况。例如在以计算机网络作为运行环境的图书管理系统中,服务器需对来自各个不同的客户机的进程进行管理,决定某个特定进程(如查询子进程、借还书子进程)的唤醒、启动、关闭等操作,从而控制整个网络协调、有序地工作。
我们通过扩展Booch对Ada任务的表示法来表示进程视图。从体系结构角度来看,进程视图的标记元素如图2.7所示。图2.7进程视图中使用的标记符号有很多风格适用于进程视图,如管道和过滤器风格、客户/服务器(多客户/单服务器,多客户/多服务器)风格等。图2.8是2.2.1节中的ACS系统的局部进程视图。
在图2.8中,所有终端均由同一个终端进程进行处理,由其输入队列中的消息驱动。控制器对象在组成控制器进程的三个任务之一中执行,慢周期(200 ms)控制器任务扫描所有挂起(suspend)终端,把任何一个活动的终端置入快周期(10 ms)控制器任务的扫描列表;快周期控制器任务检测任何显著的状态改变,并把改变的状态传递给主控制器任务;主控制器任务解释改变,通过消息与相应的终端进行通信。在这里,通过共享内存来实现在控制器进程中传递消息的功能。图2.8ACS系统的局部进程视图
4.物理视图
物理视图(physicalview)主要考虑如何把软件映射到硬件上,它通常要考虑系统性能、规模、可靠性等,以解决系统拓扑结构、系统安装、通信等问题。当软件运行于不同的结点上时,各视图中的构件都直接或间接地对应于系统的不同结点。因此,从软件到结点的映射要有较高的灵活性,当环境改变时,对系统其他视图的影响要小。
大型系统的物理视图可能会变得十分混乱,因此可以与进程视图的映射一起,以多种形式出现,也可单独出现。图2.9是物理视图的标记元素集合。图2.9物理视图中使用的标记符号图2.10所示是一个大型ACS系统可能的硬件配置,图2.11和图2.12是进程视图的两个不同的物理视图映射,分别对应一个小型的ACS和一个大型的ACS。图中,C、F和K是三个不同容量的计算机类型,支持三个不同的可执行文件。图2.10ACS系统的物理视图图2.11具有进程分配的小型ACS系统的物理视图图2.12具有进程分配的大型ACS系统的物理视图
5.场景
场景(scenarios)可以看做是那些重要系统活动的抽象,它使4个视图有机地联系起来,从某种意义上说,场景是最重要的需求抽象。在开发体系结构时,它可以帮助设计者找到体系结构的构件和它们之间的作用关系;同时,也可以用场景来分析一个特定的视图,或描述不同视图构件间的相互作用。场景可以用文本表示,也可以用图形表示。例如,图2.13是一个小型ACS系统的场景片段,相应的文本表示如下过程:
①小王的电话控制器检测和验证电话从挂机到摘机状态的转变,且发送一个消息以唤醒相应的终端对象。②终端分配一定的资源,且通知控制器发出某种拨号音。
③控制器接收所拨号码并传给终端。
④终端使用编号计划分析号码。
⑤当一个有效的拨号序列进入时,终端打开一个会话。
从以上分析可知,逻辑视图和开发视图描述系统的静态结构,而进程视图和物理视图描述系统的动态结构。对于不同的软件系统来说,侧重的角度也有所不同。例如,对于管理信息系统,比较侧重于从逻辑视图和开发视图来描述系统,而对于实时控制系统,则比较注重于从进程视图和物理视图来描述系统。图2.13本地呼叫场景的一个原型2.2.2软件体系结构的核心模型
综合软件体系结构的概念,体系结构的核心模型由五种元素组成:构件、连接件、配置(configuration)、端口(port)和角色(role)。其中构件、连接件和配置是最基本的元素。
构件是具有某种功能的可重用的软件模板单元,表示了系统中主要的计算元素和数据存储。构件有两种:复合构件和原子构件。复合构件由其他复合构件和原子构件连接而成;原子构件是不可再分的构件,底层由实现该构件的类组成。这种构件的划分提供了体系结构的分层表示能力,有助于简化体系结构的设计。连接件表示了构件之间的交互。简单的连接件如管道(pipe)、过程调用(procedurecall)、事件广播(eventbroadcast)等。更为复杂的交互有客户/服务器(client/server)通信协议、数据库和应用之间的SQL连接等。
配置表示了构件和连接件的拓扑逻辑和约束。
另外,构件作为一个封装的实体,只能通过其接口与外部环境交互。构件的接口由一组端口组成,每个端口都表示了构件和外部环境的交互点。通过不同的端口类型,一个构件可以提供多重接口。一个端口可以非常简单,如过程调用,也可以表示更为复杂的界面(包含一些约束),如必须以某种顺序调用的一组过程调用。连接件作为建模软件体系结构的主要实体,同样也有接口。连接件的接口由一组角色组成,每一个角色都定义了该连接件表示的交互参与者。二元连接件有两个角色,如RPC的角色为caller和callee,pipe的角色是reading和writing,消息传递连接件的角色是sender和receiver。有的连接件有多于两个的角色,如事件广播有一个事件发布者角色和任意多个事件接收者角色。
综上所述,我们可将软件体系结构的核心模型表示为图2.14。图2.14软件体系结构的核心模型2.2.3软件体系结构的生命周期模型
对于软件项目的开发来说,一个清晰的软件体系结构是首要的。传统的软件开发过程可以划分为从概念直到实现的若干个阶段,包括问题定义、需求分析、软件设计、软件实现及软件测试等。软件体系结构的建立应在需求分析之后,软件设计之前。在建立软件体系结构时,设计者主要从结构的角度对整个系统进行分析,选择恰当的构件、构件间的相互作用以及它们的约束,最后形成一个系统框架以满足用户的需求,为软件设计奠定基础。
下面从各个阶段的功能出发,分析这几个层次之间的关系。
1.需求分析阶段
需求分析阶段的任务是根据需求,决定系统的功能。在此阶段,设计者应对目标对象和环境做细致深入的调查,收集目标对象的基本信息,从中找出有用的信息。这是一个抽象思维、逻辑推理的过程,其结果是生成软件规格说明。需求是指用户对目标软件系统在功能、行为、性能、设计约束等方面的期望,需求分析过程主要是获取用户需求,确定系统中所要用到的构件。体系结构需求包括需求获取、生成类图、对类分组、把类打包成构件和需求评审等过程。其中需求获取主要是定义开发人员必须实现的软件功能,使得用户能完成他们的任务,从而满足业务上的功能需求。与此同时,还要获得软件质量属性,满足一些非功能需求。获取了需求之后,就可以利用工具(例如RationalRose)自动生成类图,然后对类进行分组,简化类图结构,使之更清晰。分组之后,再把类簇打包成构件,这些构件可以分组合并成更大的构件。
最后进行需求评审,即组织一个由不同代表(如分析人员、客户、设计人员、测试人员)组成的小组,对体系结构需求及相关构件进行仔细的审查。审查的主要内容包括所获取的需求是否真实反映了用户的要求、类的分组是否合理以及构件合并是否合理等。
2.建立软件体系结构阶段
在这个阶段,体系结构设计师主要从结构的角度对整个系统进行分析,选择恰当的构件,根据构件间的相互作用关系以及对它们的约束,形成一个系统框架以满足用户需求,为设计奠定基础。
在建立体系结构的初期,选择一个合适的体系结构风格是首要的。选择了风格之后,把在体系结构需求阶段已确认的构件映射到体系结构中,将产生一个中间结构。然后,为了把所有已确认的构件集成到体系结构中,必须认真分析这些构件的相互作用和关系。一旦决定了关键构件之间的相互作用和关系,就可以在前面得到的中间结构的基础上进行细化。
3.设计阶段
设计阶段主要是对系统进行模块化并决定描述各个构件间的详细接口、算法和数据类型,对上支持建立软件体系结构阶段所形成的框架,对下提供实现基础。
一旦设计了软件体系结构,我们必须邀请独立于系统开发的外部人员对体系结构进行评审。
4.实现阶段
实现阶段将设计阶段设计的算法及数据类型用程序语言表示,以满足设计体系结构和需求分析的要求,从而得到满足设计需求的目标系统。整个实现过程是以复审后的文档化的体系结构说明书为基础的,每个构件都必须满足软件体系结构中说明的对其他构件的责任。这些决定(即实现的约束)是在系统级或整个项目范围内做出的,每个构件上工作的实现者是看不见的。
在体系结构说明书中,已经定义了系统中的构件与构件之间的关系。在体系结构层次上,因为构件接口约束对外唯一地代表了构件,所以可以从构件库中查找符合接口约束的构件,必要时还可开发新的满足要求的构件。然后,按照设计提供的结构,通过组装支持工具把这些构件的实现体组装起来,完成整个软件系统的连接与合成。
最后一步是测试,包括单个构件的功能性测试和组装应用的整体功能与性能测试。
由此可见,软件体系结构在系统开发的全过程中起着基础的作用,是设计的起点和依据,同时也是装配和维护的指南。与软件本身一样,软件体系结构也有其生命周期,图2.15形象地表示了体系结构的生命周期。图2.15软件体系结构的生命周期模型
(1)软件体系结构的非形式化描述。在软件体系结构的非形式化描述(softwarearchitectureinformaldescription)阶段,对软件体系结构的描述尽管常用自然语言,但是该阶段的工作却是创造性和开拓性的。一种软件体系结构产生时,其思想通常是简单的,并常常由软件设计师用非形式化的自然语言表示概念、原则。例如,客户/服务器体系结构就是为适应分布式系统的要求,从主从式演变而来的一种软件体系结构。
(2)软件体系结构的规范描述和分析。软件体系结构的规范描述和分析(softwarearchitecturespecificationandanalysis)阶段通过运用合适的形式化数学理论模型对第1阶段的体系结构的非形式化描述进行规范定义,从而得到软件体系结构的形式化规范描述,以使软件体系结构的描述精确、无歧义,进而分析软件体系结构的性质,如无死锁性、安全性、健壮性等。分析软件体系结构的性质有利于在系统设计时选择合适的软件体系结构,避免盲目选择。
(3)软件体系结构的求精及其验证。软件体系结构的求精及其验证(softwarearchitecturerefinementandverification)阶段对已设计好的软件体系结构进行验证和求精。大型系统的软件体系结构总是通过从抽象到具体、逐步求精而达到的。一般来说,抽象是人们在处理复杂问题和对象时必不可少的思维方式,软件体系结构也不例外,但是过高的抽象却使软件体系结构难以真正在系统设计中实施。如果软件体系结构的抽象粒度过大,就需要对体系结构进行求精、细化,直至其能够在系统设计中实施为止。在软件体系结构的每一步求精过程中,需要对不同抽象层次的软件体系结构进行验证,以判断较具体的软件体系结构是否与较抽象的软件体系结构的语义一致,能否实现抽象的软件体系结构。
(4)软件体系结构的实施。软件体系结构的实施(softwarearchitectureenactment)阶段将求精后的软件体系结构实施于系统的设计中,并将软件体系结构的构件和连接件等有机地组织在一起,形成系统设计的框架。
(5)软件体系结构的演化和扩展。当体系结构实施后,就进入软件体系结构的演化和扩展(softwarearchitectureevolutionandextension)阶段。在实施软件体系结构时,性能、容错、安全性、互操作性、自适应性等非功能性质将影响软件体系结构的扩展和改动,这称为软件体系结构的演化。由于对软件体系结构的演化常常由非功能性质的非形式化需求描述引起,因而需要重复第(1)步。如果由于功能和非功能性质对以前的软件体系结构进行演化,就要涉及软件体系结构的理解,需要进行软件体系结构的逆向工程和再造工程。
(6)软件体系结构的提供、评价和度量。软件体系结构的提供、评价和度量(softwarearchitectureprovision,evaluationandmetric)阶段根据将软件体系结构实施于系统设计后系统的实际运行情况,对软件体系结构进行定性的评价和定量的度量,以利于对软件体系结构的重用,并取得经验教训。
(7)软件体系结构的终结。如果一个软件系统的软件体系结构进行了多次演化和修改,软件体系结构已变得难以理解,甚至不能达到系统设计的要求,不能适应系统的发展,这就说明该软件体系结构已经过时,应该摈弃,以全新的满足系统设计要求的软件体系结构取而代之。这个阶段被称为软件体系结构的终结(softwarearchitecturetermination)阶段。 2.3基于体系结构的描述
2.3.1软件体系结构的描述方法
1.图形表达工具
对于软件体系结构的描述和表达,一种简洁易懂且使用广泛的方法是采用由矩形框和有向线段组合而成的图形表达工具。在这种方法中,矩形框代表抽象构件,框内标注的文字为抽象构件的名称,有向线段代表辅助各构件进行通信、控制或关联的连接件。图2.16表示某软件辅助理解和测试工具的部分体系结构描述。图2.16某软件辅助理解和测试工具的部分体系结构描述目前,这种图形表达工具在软件设计中占据着主导地位。尽管由于在术语和表达语义上存在着一些不规范和不精确,以矩形框和线段为基础的传统图形表达方法在不同系统和不同文档之间有着许多不一致甚至矛盾,但该方法仍然以其简洁易用的特点在实际的设计和开发工作中被广泛使用,并为工作人员传递了大量重要的体系结构思想。
为了克服传统图形表达方法中所缺乏的语义特征,有关研究人员试图通过增加含有语义的图元素的方式来扩展图形表达方法。
2.模块内连接语言
软件体系结构的第二种描述和表达方法是采用将一种或几种传统程序设计语言的模块连接起来的模块内连接语言(ModuleInterconnectionLanguage,MIL)。由于程序设计语言和模块内连接语言具有严格的语义基础,因此它们能对较大的软件单元进行描述,诸如定义/使用和扇入/扇出等操作。例如,Ada语言采用use实现包的重用,Pascal语言采用过程(函数)模块的交互等。
MIL方式对模块化的程序设计和分段编译等程序设计与开发技术确实发挥了很大的作用。但是由于这些语言处理和描述的软件设计开发层次过于依赖程序设计语言,因而限制了它们处理和描述比程序设计语言元素更为抽象的高层次软件体系结构元素的能力。
3.基于软构件的系统描述语言
软件体系结构的第三种描述和表达方法是采用基于软构件的系统描述语言。基于软构件的系统描述语言将软件系统描述成一种由许多以特定形式相互作用的特殊软件实体构造而成的组织或系统。例如,一种多变配置语言(ProteusConfigurationLanguage,PCL)就可以在一个较高的抽象层次上对系统的体系结构建模;Darwin最初用作设计和构造复杂分布式系统的配置说明语言,因其具有动态特性,也可用来描述动态体系结构。这种表达和描述方式虽然也是较好的一种以构件为单位的软件系统描述方法,但是它们所面向和针对的系统元素仍然是一些层次较低的以程序设计为基础的通信协作软件实体单元,而且这些语言所描述和表达的系统一般而言都是面向特定应用的特殊系统,这些特性使得基于软构件的系统描述仍然不是十分适合软件体系结构的描述和表达。
4.软件体系结构描述语言
软件体系结构的第四种描述和表达方法是参照传统程序设计语言的设计和开发经验,重新设计、开发和使用针对软件体系结构特点的专门的软件体系结构描述语言(ArchitectureDescriptionLanguage,ADL)。由于ADL是在吸收了传统程序设计中语义严格精确的特点基础上,针对软件体系结构的整体性和抽象性特点,定义和确定适合于软件体系结构表达与描述的有关抽象元素的,因此,ADL是当前软件开发和设计方法学中一种发展很快的软件体系结构描述方法。目前,已经有几十种常见的ADL。我们将在2.3.3节详细介绍几种主要的软件体系结构描述语言。2.3.2软件体系结构的描述框架标准
鉴于体系结构描述的概念与实践的不统一,IEEE于1995年8月成立了体系结构工作组。该工作组综合体系结构描述研究成果,并参考业界的体系结构描述的实践,负责起草了体系结构描述框架标准IEEEP1471,并于2000年9月21日通过IEEE-SA标准委员会评审。
IEEEP1471适用于软件密集的系统,其目标在于:便于体系结构的表达与交流,并通过体系结构要素及其实践标准化,奠定质量与成本的基础。该标准详细介绍了一套体系结构描述的概念框架,并给出建立框架的思路。同时,该标准还讨论了体系结构描述实践。在应用体系结构描述的推荐标准时,应该遵循如下要求:
●体系结构的存档要求;
●能识别人员及其关系;
●体系结构视点的选择(视点的具体规格说明);
●体系结构视点;
●体系结构视点之间的一致性;
●体系结构原理。
IEEEP1471仅仅提供了体系结构描述的概念框架及体系结构描述实践应该遵循的规范,但对如何描述以及具体的描述技术等方面却缺乏更进一步的指导。在IEEEP1471推荐的体系结构描述的概念框架基础上,Rational起草了可重用的软件资产规格说明,专门讨论了体系结构描述的规格说明,提出了一套易于重用的体系结构描述规范。该建议草案已经提交OMG,可望成为体系结构描述的行业规范。
可重用的体系结构描述框架建议,基于RUP(RationalUnitedProcess)、采用UML模型描述软件的体系结构,认为体系结构描述的关键是定义视点、视图以及建模元素之间的映射关系。可以从四个视点出发描述体系结构,即需求视点、设计视点、实现视点和测试视点,并在此基础上提出了七种体系结构视图,即用例视图、域视图、非功能需求视图、逻辑视图、实现视图、过程视图和部署视图。然后,从系统建模的角度考虑多个视图之间的映射关系,并建议了这些视图的表示和视图之间的映射关系的表示。
Rational的建议标准采纳了IEEEP1471中提出的体系结构描述概念模型,覆盖了“4+1”,体系结构模型中的四个视图,并在原则上讨论了视图以及视图之间映射的表示问题。与IEEEP1471相比,该建议标准的体系结构描述方案涉及面比较窄,所注重的层次比较低,因而更具体。同时由于将体系结构的描述限于UML和RUP,因而具有一定的局限性。但该建议标准结合了业界已经广泛采用的建模语言和开发过程,因此易于推广。2.3.3软件体系结构的描述语言
ADL是这样一种形式化语言,它在底层语义模型的支持下,为软件系统的概念体系结构建模提供了具体语法和概念框架。基于底层语义的工具为体系结构的表示、分析、演化、细化、设计过程等提供支持,有如下三个基本元素:
●构件:计算或数据存储单元。
●连接件:用于构件之间交互建模的体系结构构造块及支配这些交互的规则。
●体系结构配置:描述体系结构的构件与连接件的连接图。主要的体系结构描述语言有Aesop、MetaH、C2、Rapide、SADL、UniCon和Wright等,尽管它们都描述软件体系结构,却有不同的特点。Aesop支持体系结构风格的应用;MetaH为设计者提供了关于实时电子控制软件系统的设计指导;C2支持基于消息传递风格的用户界面系统的描述;Rapide支持体系结构设计的模拟并提供了分析模拟结果的工具;SADL提供了关于体系结构求精的形式化基础;Unicon支持异构的构件和连接类型,并提供了关于体系结构的高层编译器;Wright支持体系结构构件之间交互的说明和分析。这些ADL强调了体系结构不同的侧面,对体系结构的研究和应用起到了重要的作用,但其也有负面的影响。每一种ADL都以独立的形式存在,描述语法不同且互不兼容,同时又有许多共同的特征,这使设计人员很难选择一种合适的ADL。如果要设计特定领域的软件体系结构,就需要从头开始描述。
1.ADL与其他语言的比较
按照MaryShaw和DavidGarlan的观点,典型的ADL在充分继承和吸收传统程序设计语言的精确性和严格性特点的同时,还应该具有构造、抽象、重用、组合、异构和分析推理等各种能力和特性。其中:
●构造能力指的是ADL能够使用较小的独立体系结构元素来建造大型软件系统。
●抽象能力指的是ADL使得软件体系结构中的构件和连接件描述可以只关注它们的抽象特性,而不管其具体的实现细节。●重用能力指的是ADL使得组成软件系统的构件、连接件甚至是软件体系结构都成为软件系统开发和设计的可重用部件。
●组合能力指的是ADL使得其描述的每一系统元素都有其自己的局部结构,这种描述局部结构的特点使得ADL支持软件系统的动态变化组合。
●异构能力指的是ADL允许多个不同的体系结构描述可以存在关联。
●分析和推理能力指的是ADL允许对其描述的体系结构进行多种不同的性能和功能上的多种推理分析。根据这些特点,我们可以将下面这样的语言排除在ADL之外:高层设计符号语言、MIL、编程语言、面向对象的建模符号、形式化说明语言。ADL与需求语言的区别在于后者描述的是问题空间,而前者则扎根于解空间。ADL与建模语言的区别在于后者对整体行为的关注要大于对部分的关注,而ADL集中在构件的表示上。ADL与传统的程序设计语言的构成元素既有许多相同和相似之处,又有着很大的不同。
表2.1和表2.2给出了程序设计语言和ADL的典型元素的属性和含义比较,以及软件体系结构中经常出现的一些构件和连接件元素。表2.1典型元素含义比较表2.2常见的软件体系结构元素
2.ADL的构成要素
前面,我们提到了体系结构描述的基本构成要素有构件、连接件和体系结构配置,可参见图2.14。
1)构件
构件是一个计算单元或数据存储,也就是说,构件是计算与状态存在的场所。在体系结构中,一个构件可能小到只有一个过程或大到整个应用程序,它可以要求自己的数据或执行空间,也可以与其他构件共享这些空间。作为软件体系结构构造块的构件,其自身也包含了多种属性,如接口、类型、语义、约束、演化和非功能属性等。接口是构件与外部世界的一组交互点。与面向对象方法中的类说明相同,ADL中的构件接口说明了构件提供的服务(消息、操作、变量)。为了能够充分地推断构件及包含它的体系结构,ADL提供了能够说明构件需要的工具,这样,接口就定义了构件能够提出的计算委托及其用途上的约束。
构件作为一个封装的实体,只能通过其接口与外部环境交互。构件的接口由一组端口组成,每个端口表示了构件和外部环境的交互点。通过不同的端口类型,一个构件可以提供多重接口。一个端口可以非常简单,如过程调用;也可以表示更为复杂的界面,如必须以某种顺序调用的一组过程调用。构件类型是实现构件重用的手段,它保证了构件能够在体系结构描述中多次实例化,并且每个实例可以对应于构件的不同实现。抽象构件类型也可以参数化,进一步促进重用。现有的ADL都将构件类型与实例区分开来。
由于基于体系结构开发的系统大都是大型、长时间运行的系统,因而系统的演化能力显得格外重要。构件的演化能力是系统演化的基础。ADL是通过构件的子类型及其特性的细化来支持演化过程的。目前,只有少数几种ADL部分地支持演化,对演化的支持程度通常依赖于所选择的程序设计语言,其他ADL将构件模型看做是静态的。
2)连接件
连接件是用来建立构件间的交互以及支配这些交互规则的体系结构构造模块。与构件不同,连接件可以不与实现系统中的编译单元对应,它们可能以兼容消息路由设备实现(如C2),也可以共享变量、表入口、缓冲区、对连接器的指令、动态数据结构、内嵌在代码中的过程调用序列、初始化参数、客户服务协议、管道、数据库、应用程序之间的SQL语句等形式出现。大多数ADL都将连接件作为第一类实体,也有不将连接件作为第一类实体的ADL。
连接件作为建模软件体系结构的主要实体,同样也有接口。连接件的接口由一组角色组成,每一个角色定义了该连接件表示的交互参与者。二元连接有两个角色,如消息传递连接件的角色是发送者和接收者。有的连接件有多于两个的角色,如事件广播有一个事件发布者角色和任意多个事件接受者角色。
显然,连接件的接口是一组它与所连接构件之间的交互点。为了保证体系结构中的构件连接以及它们之间的通信正确,连接件应该导出所期待的服务作为它的接口。连接件能够推导出软件体系结构的形成情况。体系结构配置中要求构件端口与连接件角色是显式连接。
体系结构级的通信需要用复杂协议来表达。为了抽象这些协议并使之能够重用,ADL应该将连接件构造为类型。构造连接件特性可以把用通信协议定义的类型系统化并使其独立于实现,或者作为内嵌的、基于它们的实现机制的枚举类型。为完成对构件接口的有用分析,保证跨体系结构抽象层细化的一致性,强调互联与通信约束等,体系结构描述提供了连接件协议以及变换语法。为了确保执行正确的交互协议,建立起内部连接件依赖关系,确定用途边界,就必须说明连接件约束。ADL可以通过强制风格不变性来实现约束,或通过接受属性限制给定角色的服务。
3)体系结构配置
体系结构配置或拓扑是描述体系结构的构件与连接件的连接图。体系结构配置提供信息来确定构件是否正确连接、接口是否匹配、连接件构成的通信是否正确,并说明实现要求行为的组合语义。体系结构适合于描述大的、生命周期长的系统。利用配置来支持系统的变化,使不同技术人员都能理解并熟悉系统。为帮助开发人员在一个较高的抽象层上理解系统,就需要对软件体系结构进行说明。为了使开发者与有关人员之间的交流容易些,ADL必须以简单的、可理解的语法来配置结构化信息。理想的情况是从配置说明中澄清系统结构,即不需研究构件与连接件就能使构建系统的各种参与者理解系统。体系结构配置说明除文本形式外,有些ADL还提供了图形说明形式。文本描述与图形描述可以互换。多视图、多场景的体系结构说明方法在最新的研究中得到了明显的加强。为了在不同细节层次上描述软件系统,ADL将整个体系结构作为另一个较大系统的单个构件,也就是说,体系结构具有复合或等级复合的特性。另一方面,体系结构配置支持采用异构构件与连接件。这是因为软件体系结构的目的之一是促进大规模系统的开发,即倾向于使用已有的构件与不同粒度的连接件,这些构件与连接件的设计者、形式模型、开发者、编程语言、操作系统、通信协议可能都不相同。另外一个事实是,大型的、长期运行的系统是在不断增长的,因而,ADL必须支持可能增长的系统的说明与开发。大多数ADL提供了复合特性,所以,任意尺度的配置都可以相对简洁地在足够的抽象高度表示出来。我们知道,体系结构设计是整个软件生命周期中关键的一环,一般在需求分析之后、软件设计之前进行。而形式化的、规范化的体系结构描述对于体系结构的设计和理解都是
非常重要的。因此,ADL如何能够承上启下将是十分重要的问题,一方面是体系结构描述如何向其他文档转移,另一方面是如何利用需求分析成果来直接生成系统的体系结构说明。现有的ADL大多是与领域相关的,这不利于对不同领域的体系结构进行说明。这些针对不同领域的ADL在某些方面又大同小异,造成了资源的冗余。有些ADL可以实现构件与连接件的演化,但这样的演化能力是有限的,这样的演化大多是通过子类型实现的。尽管现有的ADL都提供了支持工具集,但将这些ADL与工具应用于实际系统开发中的成功范例还很有限。支持工具的可用性与有效性较差,严重地阻碍了这些ADL的广泛应用。
2.4基于体系结构的软件设计
2.4.1基于体系结构的设计模式
1.设计模式概述
随着面向对象技术的出现和广泛使用,一方面软件的可重用性在一定程度上已经有所解决,另一方面对软件可重用性的要求也越来越高。设计面向对象的软件很难,而设计可重复使用的面向对象的软件难度则更大。开发人员必须找到适当的对象,将它们分解到粒度合适的类、定义类接口和继承体系,并建立它们之间的关联。在某个时候,设计师的设计可能是针对当前的具体问题而进行的,但应该努力使其通用化以适应未来的问题和需求。在一个设计完成之前,有经验的面向对象的设计师往往要重复设计若干次,而且每次都要进行改进。他们知道,不能只用最初的方法解决每个问题,但可以常常重复使用那些过去用过的解决方案。这些经验正是他们成为专家的法宝,也就是设计经验的价值。
因此,我们可将设计面向对象软件的经验记录成“设计模式(designpattern)”。每个设计模式都有系统命名、解释和评价了的面向对象系统中的一个重要的设计。我们的目标是将设计经验收集成人们可以有效利用的模型。为此,可以记录一些最重要的设计模式,并以目录的形式表现出来。利用设计模式可方便地重用成功的设计和结构。把已经证实的技术表示为设计模式,使它们更加容易被新系统的开发者所接受。设计模式帮助设计师选择可使系统重用的设计方案,避免选择危害可重用性的方案,它还提供了类和对象接口的明确的说明书和这些接口的潜在意义。
设计模式的概念最早是由名为ChristopherAlexander的建筑师提出来的,他试图找到一种结构化、可重用的方法,以在图纸上捕捉到建筑物的基本要素。逐渐地他的思想影响了软件研究,并开始流行起来。Alexander提出的模式是指经过时间考验的解决方案,使用此模式可以降低解决问题的复杂度。在编程时,很多情况下代码都不是从头编写,而是模仿得来的,即从别处搬过来,再经过一定改造使之适应当前情况。设计模式可以视为这种模仿的一种抽象,包含一组规则,描述了如何在软件开发领域中完成一定的任务。从这个意义上讲,所有的算法都属于编程领域的设计模式。面向对象的设计模式用来解决如何在面向对象软件开发中完成一定的任务。
在介绍设计模式的具体定义之前,我们先看一个例子:模型—视图—控制器(Model-View-Controller,MVC)模式。在开发人机界面软件时考虑这种模式。用户界面承担着向用户显示问题模型、与用户进行输入/输出交互的作用。用户希望保持交互操作界面的相对稳定,但更希望根据需要改变和调整显示的内容和形式。例如,要求支持不同的界面标准或得到不同的显示效果,适应不同的操作需求。这就要求界面结构能够在不改变软件功能的情况下,支持用户对界面结构的调整。要做到这一点,从界面构成的角度看,困难在于:在满足对界面要求的同时,如何使软件的计算模型独立于界面的构成。MVC就是这样的一种交互界面的结构组织模型。对于界面设计可变性的需求,MVC把交互系统的组成分解成模型、视图、控制三种构件。其中模型构件独立于外在显示内容和形式,是软件所处理的问题逻辑的内在抽象,它封装了问题的核心数据、逻辑和功能的计算关系,独立于具体的界面表达和输入/输出操作;视图构件把表示模型数据及逻辑关系和状态的信息以特定形式展示给用户,它从模型获得显示信息,对于相同的信息可以有多个不同的显示形式或视图;控制构件处理用户与软件的交互操作,其职责是决定软件的控制流程,确保用户界面与模型间的对应联系,它接收用户的输入,将输入反馈给模型,进而实现对模型的计算控制,它是使模型和视图协调工作的部件。模型、视图与控制器的分离,使得一个模型可以具有多个显示视图。如果用户通过某个视图的控制器改变了模型的数据,所有其他依赖于这些数据的视图都应反映出这些变化。因此,无论何时发生了何种数据变化,控制器都会将变化通知给所有的视图,导致显示的更新。
图2.17所示的对象模型技术类图描述了MVC解决方案。图2.17MVC解决方案从图2.17中我们可以导出软件体系结构模式的属性:一个模式关注一个在特定设计环境中出现的设计问题,并为它提供一个解决方案。在我们的例子中,问题是支持用户界面的可变性。开发人机交互软件系统时,这个问题就会出现。
所谓设计模式,简单地理解,就是一些设计面向对象的软件开发的经验总结。一个设计模式事实上是系统地命名、解释和评价某一个重要的可重现的面向对象的设计方案。正如Alexander所说:“每一个模式都描述了一个在我们身边一再发生的问题,它告诉我们这个问题的解的关键,以使我们可以成千上万次地利用这个解,而不需要再一次去重新解它。”尽管Alexander所说的是有关建筑和城镇的模式,但它同样适用于面向对象的设计模式,只不过要解决的问题是软件开发中一再出现的问题。受到普通认可的设计模式的定义是由DirkRiehle和HeinzZullighoven给出的:“模式是指从某个具体的形式中得到的一种抽象,在特殊的非任意性的环境中,该形式不断地重复出现。”
模式的概念是“随设计中要解决的问题的变化而变化的”。更明确地说,重复发生的具体形式就是这一重复出现的问题的解。但是一个模式又并不仅仅是具体问题的解,因为具体问题是在一个特殊的环境中发生的,因此有很多复杂的考虑因素。给定一个环境后,所提出的问题包含了一些平衡各方面考虑的结构,或称为“权衡”。使用模式的形式,解决方案的描述可以把握住方案所体现的本质,故而别人可以从中学到一些东西,进而在相似的情况下可以进行应用。每个模式都有一个名字,帮助我们讨论模式和它所给出的信息。综上所述,我们认为,一个软件体系结构的模式描述了一个出现在特定设计语境中的特殊的再现设计问题,并为它的解决提供了一个经过充分验证的通用方案。解决方案通过描述其组成构件及其责任和相互关系以及它们的协作方式来具体指定。
一个好的模式必须做到以下几点。
●解决一个问题:从模式可以得到解,而不仅仅是抽象的原则或策略。
●是一个被证明了的方案:模式通过一个记录得到解,而不是通过理论或推测。
●解并不是显然的:许多解决问题的方法(比如软件设计范例或方法)是从最基本的原理得到解;而还有一些是以非直接的方式得到解。●描述了一种关系:模式并不仅仅描述模块,它给出了更深层的系统结构和机理。
●模式有重要的人为因素:所有的软件服务于人类的舒适或生活质量,而最好的模式追求它的实用性和美学。
关于设计模式,目前的研究方向主要有:设计模式与其他面向对象设计方法(如特定领域的框架)的关系,它们各自的优劣和适应范围。除此而外,人们还在各个方面总结设计模式(如通信等领域),并研究如何让设计模式的使用更加自动化等。关于设计模式还有很多工作要做,而且它并不是一个只要看一遍就能掌握的方法。在工作中要不断总结、不断回顾以前使用过的设计模式。不同的模式之间有联系,同时也有各自的优缺点,在应用中要注意仔细考虑、权衡利弊、加以取舍,只有这样才可能真正用好设计模式。
2.设计模式的组成
1)设计模式的基本成分
一般来说,一个模式有以下四个基本成分:
(1)模式名称。模式名称通常用来描述一个设计问题及其解法和结果,由一到两个词组成。模式名称的产生使我们可以在更高的抽象层次上进行设计并交流设计思想,因此,寻找好的模式名称是一个很重要也很困难的工作。
(2)问题。问题告诉我们什么时候要使用设计模式、解释问题及其背景。例如,模型—视图—控制器模式关心用户界面经常变化的问题,它可能描述诸如如何将一个算法表示成一个对象这样的特殊设计问题。在应用这个模式之前,也许还要给出一些该模式的适用条件。模式的问题陈述用一个强制条件(force)集来表示。force最初是从建筑学和Alexander那里借用来的,模式组织使用术语“强制条件”来说明问题要解决时应该考虑的各个方面,例如:
●解决方案必须满足的需求,如对等进程间通信必须是高效的。
●必须考虑的约束,如进程间通信必须遵循特定协议。
●解决方案必须具有的期望特性,如软件更改应该是容易的。●模型一视图一控制器模式指出了它的强制条件:用户界面必须易于修改,但软件的核心功能不能被修改所影响。一般地,强制条件从多个角度讨论问题并有助于设计师了解它的细节,它可以相互补充或相互矛盾。例如,系统的可扩展性与代码的最小化构成了两个相互矛盾的强制条件。如果希望系统可扩展,那么就应倾向于使用抽象超类;如果想使代码最小化(例如用于嵌入式系统),就不能承受抽象超类的“奢侈”。但更重要的是,强制条件是解决问题的关键,它们平衡得越好,对问题的解决方案就越好。所以,强制条件的详细讨论是问题陈述的重要部分。
(3)解决方案。解决方案描述设计的基本要素、它们的关系、各自的任务以及相互之间的合作。解决方案并不是针对某一个特殊问题而给出的。设计模式提供有关设计问题的一个抽象描述以及如何解决问题。一个模式就像一个可以在许多不同环境下使用的模板,抽象的描述使我们可以把该模式应用于解决许多不同的问题。
模式的解决方案部分给出了如何解决问题,或者更恰当地说是如何平衡与之相关的强制条件。在软件体系结构中,这样的解决方案包括两个方面。
●每个模式规定了一个特定的结构,即元素的一个空间配置。例如,MVC模式的描述包括以下语句:“把一个交互应用程序划分成三部分:处理、输入和输出。”●每个模式规定了运行期间的行为。例如,MVC模式的解决方案部分包括以下陈述:“控制器接收输入,而输入往往是鼠标移动、单击鼠标按键或键盘输入等事件。事件转换成服务请求,这些请求再发送给模型或视图。”
值得注意的是:解决方案不必解决与问题相关的所有强制条件,可以仅仅集中于特殊的强制条件,而对于剩下的强制条件进行部分解决或完全不解决,特别是在强制条件相互矛盾时。
(4)结果。结果描述应用设计模式后的结果和权衡,比较与其他设计方法的异同,得到应用设计模式的代价和优点。对于软件设计来说,通常要考虑的是空间和时间的权衡,也会涉及语言问题和实现问题。对于一个面向对象的设计而言,可重用性很重要,结果还包括对系统灵活性、可扩充性及可移植性的影响。
另外,不同的观点会影响人们对什么是设计模式的解释。某一个人的模式对另一个人来说可能只是一个基本的构造块。这里把设计模式处理到一定的抽象程度,它不用于直接编码或类重用,也不是复杂到可作为一个完整的应用或子系统的领域专用设计,而是对一定的对象与类的关系进行描述,进而可对其进行一定程度的修改,解决在一定条件下的通用设计问题。设计模式命名、抽象并确定了一个普遍的设计结构,有助于得到可重用的面向对象的设计,还确定了参与的类和实例、它们的地位和协作以及责任的分配。每一个设计模式都集中于特定的面向对象设计问题,描述了何时使用、是否能在其他设计约束条件下使用及使用后的结果和折中。
2)设计模式的描述
如果我们要理解和讨论模式,就必须以适当形式描述模式。好的描述有助于我们立即抓住模式的本质,即模式关心的问题是什么,以及提出的解决方案是什么。
模式也应该以统一的方式来描述,这有助于我们对模式进行比较,尤其在我们为一个问题寻求可选择的解决方案时。那么,如何描述一个设计模式呢?仅仅依靠图示的方法是不够的。尽管图示的方法很重要也很有用,但它们只能把设计的最终结果表示成一些类和对象的关系。事实上,为了重用该设计,我们还应该记录产生这个设计的决策和权衡过程。具体的实例也很重要,从中可以看到设计模式的运转过程。模式概念的创始者Alexander采用下面的格式来描述设计模式:
IFyoufindyourselfinCONTEXT
ForexampleEXAMPLES,
WithPROBLEM
EntailingFORCESS
THENforsomeREASONS,
ApplyDESIGNFORMAND/ORRULE
ToconstructSOLUTION
LeadingtoNEWCONTEXTandOTHERPATTERNS
ErichGamma等人采用下面的固定模式来描述,这也是目前最常用的格式。
●模式名称和分类:模式名称和一个简短的摘要。
●目的:回答下面的问题,即本设计模式的用处,它的基本原理和目的,它针对的是什么特殊的设计问题。
●别名:由于设计模式的提取是由许多专家得到的,同一个模式可能会被不同的专家冠以不同的命名。
●动机:描述一个设计问题的方案,以及模式中类和对象的结构是如何解决这个问题的。
●应用:在什么情况下可以应用本设计模式,如何辨认这些情况。●结构:用对象模型技术对本模
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 施工污水循环利用方案
- 2026浙江台州西廊港口开发有限公司招聘市场化人员招聘工作补充笔试模拟试题及答案详解
- 2026南昌动物园招聘动物饲养员2人笔试备考试题及答案详解
- 2026年六安舒城第三中学教师招聘考试备考题库及答案详解
- 2026年德清县中小学幼儿园教师招聘笔试模拟试题及答案解析
- 2026汽车制造业市场前景分析及未来走向与资本运作攻略研究报告
- 2026年渭南华阴市人民医院招聘(14人)考试备考试题及答案详解
- 2026中国新型建材行业创新产品市场发展分析研究报告
- 2026四川雅安石棉县天钰科技有限责任公司招聘1人笔试模拟试题及答案详解
- 2026海南省直属机关第二幼儿园公开招聘事业编制人员4人笔试模拟试题及答案详解
- 高压电工进网作业知识培训
- 野战生存新版
- AO工艺污水处理过程动画详解
- JJG 1151-2025液相色谱-原子荧光联用仪检定规程
- 《劳动法常识(第3版)》中职全套教学课件
- 2025版酒店股东投资合作经营合同:创新管理模式3篇
- 国家能源集团招聘笔试题库2024
- 分部、分项工程质量验收记录
- 退休保安人员聘用合同模板
- 农业物联网技术
- 运动训练学理论
评论
0/150
提交评论