软件工程讲义-06_第1页
软件工程讲义-06_第2页
软件工程讲义-06_第3页
软件工程讲义-06_第4页
软件工程讲义-06_第5页
已阅读5页,还剩207页未读 继续免费阅读

付费下载

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

软件工程

第六章软件体系结构6.1软件体系结构的概念6.2软件体系结构的设计6.3特定领域的体系结构6.4分布式软件体系结构6.5设计模式1软件工程一个程序或计算机系统的软件体系结构包括一个或一组软件构件、软件构件的外部可见特性及其相互关系。软件构件的外部可见特性是指软件构件提供的服务、性能、特性、错误处理、共享资源使用等。软件体系结构的基本单位是软件构件,软件构件是一个软件体系结构的核心。6.1软件体系结构的概念6.1.1软件体系结构的定义2软件工程软件构件可以是子系统,也可以是模块。在它们之间没有清晰的界限,但可以依据下列两点加以区分:一个子系统独立构成系统,不依赖其他子系统提供的服务。子系统由模块或更小的子系统构成。子系统之间的交互通过它们的接口。一个模块通常是一个能提供一个或多个服务的系统构件,它能够利用其他模块提供的服务,一般不被看成一个独立的系统,模块可以由更简单的模块组成。3软件工程概念结构:从主要设计元素(构件)及其相互关联、设计原则和性能角度考虑的结构。模块结构:根据功能分解建立模块的层次结构包括模块接口、模块管理、模块控制和一致性等问题。代码结构:描述源程序,二进制程序,库文件。在开发环境下的组织包括系统资源配置管理,系统构造和对象嵌入机制OEM等。执行结构:描述系统的动态结构包括性能、调度、动态配置和不同系统间的接口等。6.1.2软件体系结构的不同形式4软件工程6.1.3在软件构件设计中应保持的性质计算功能:描述构件所实现的整体功能。结构特性:描述特定构件定义、构件打包的方式和相互交互的方式,构件如何组织以构成整个系统。附属功能:描述构件的执行效率、处理能力、环境假设、全局特性等,包括时间要求、空间要求、精确度、安全性、保密性、带宽、吞吐率、最低硬软件要求等。家族特性:描述相同和相关构件之间的关系。5软件工程纯计算构件:具有简单输入输出关系,没有运行状态变化如数值计算、过滤器、转换器等。存储构件:存放共享的、永久性的、结构化的数据。如数据库、文件、符号表、超文本等。管理构件:执行操作与运行状态紧密相关。如抽象数据类型、面向对象系统中的对象、服务器等。控制构件:管理其它构件运行的时间、时机及次序。例如,调度器、同步器等。6.1.4软件构件分类6软件工程链接构件:在实体之间传递信息。例如,通信机制、用户界面等。过程调用:在某一特定执行路径中传递执行指针。如普通过程调用、远程过程调用。数据流:相互独立的处理通过数据流进行交互,在得到数据的同时被赋予控制权限。如UNIX系统中的管道。6.1.5构件之间的连接方式7软件工程间接激活:处理因事件的发生而激活,在处理间没有直接交互。例如,事件驱动系统、自动垃圾回收等。消息传递:相互独立的处理间有明确交互,通过显式数据传递。传递可以是同步的,也可以是异步的。如TCP/IP。共享数据:构件通过同一数据空间进行并发操作。如多用户数据库,数据黑板。8软件工程6.2软件体系结构的设计软件体系结构的设计过程是为系统建立一个基本架构。它包括识别系统的主要构件和这些构件之间的通信。经典的软件体系结构框架是模型/视图/控制器(MVC,Model/View/Controller)。控制器模型视图9软件工程在MVC结构中,模型是软件应用领域中的各种对象,它们的操作独立于用户界面;视图则管理用户界面的输出;而控制器处理软件的输入。输入事件给出要发送给模型的消息。一旦模型改变了它的状态,就立即通过关联机制通知视图,让视图刷新显示。这个关联机制定义了在模型与各个视图之间的关系。类似地,控制器在输入事件发生时将对视图及模型进行控制与调度。10软件工程对于MVC,可通过开发模型的一个派生类,履行与应用相关联的处理。如用户界面通过定义视图和控制器的派生类来建立,这些派生类中许多是可复用的类,像按钮和对话框等,这样可以直接建立新的子系统。设计过程的主要活动系统构造:将系统分解为一系列基本的子系统,每一子系统是独立的软件成分。控制建模:建立系统各部分之间的控制关系的一般模型。模块分解:将子系统进一步分解为模块。11软件工程6.2.1系统构造(SystemStructuring)体系结构设计的第一步是将系统分解为一系列相互作用的子系统。在最抽象层次,系统可视为一个方框图,图中每个方框表示一个子系统。每个方框内的方框表明子系统本身还可分解为子系统。箭头表示一个子系统向另一子系统传送数据或控制。下图是一个组装机器人的系统构造。12软件工程组装机器人控制系统的方框图视觉系统对象识别系统手臂控制器机械爪控制器组装选择系统组装系统传送带控制器13软件工程体系结构方框图表示一个系统结构的概貌,软件工程师很容易理解它。这种方框图的缺点是没有反映系统构件之间关系的本质,没有表明系统的外部特性。根据各子系统如何共享数据、如何分布、如何相互交互,可开发更加特定的模型。数据仓库模型客户机/服务器模型抽象机模型14软件工程1)数据仓库模型(repositorymodel)所有共享数据都存放于数据库中,这些数据可为所有子系统存取。每个子系统保有各自的数据库,通过传送消息,可在子系统之间交换数据。大量的数据围绕一个共享数据库或数据仓库来组织。这种系统主要适用于控制系统,信息管理系统,CAD系统,CASE工具集。15软件工程集成的CASE工具集的体系结构

以数据仓库为核心设计分析器报告生成器项目数据仓库设计编辑器代码生成器设计翻译器程序编辑器16软件工程这种体系结构包括数据库、超文本系统及数据黑板系统等。它包含两种成分:一是共享的结构化数据;二是所有访问这些数据的操作。如果是因为输入数据而引起对共享数据的操作,那么这种控制策略下的体系结构就叫做数据库。如果是由共享数据的当前状态触发相应的处理,那么这种体系结构就叫做数据黑板。为此,需要存储特定知识。数据仓库模型可共享大量数据,在子系统之间无须进行数据转换。17软件工程子系统的数据模型必须与数据仓库的数据模型保持一致。如果一个新子系统的数据模型与数据仓库的数据模型冲突,很难将它集成到系统中来。不同的子系统对保密性、恢复和备份有不同的要求,而数据仓库模型将迫使所有子系统采用相同的策略。18软件工程2)客户机/服务器模型

(client/servermodel)这是一种分布式系统模型,表明各种数据和处理如何分布到各个处理器上。有一组功能各自独立的服务器,为其他子系统提供服务,如打印服务器、文件服务器、编译服务器等。有一组客户机,它们调用服务器提供的服务,也可能存在一些客户机,可并发执行客户机程序。有一个网络,使得客户机能够访问服务器。19软件工程film&picturelibrary系统的体系结构CatalogueserverVodioserverPictureserverHypertextserverCatalogueFilmclipfilesHypertextwebWide-bandwidthnetwork

Client1Client2Client3Client4Digitisedphotographs20软件工程在多用户超文本系统中存在若干服务器,它们管理和显示不同媒体的数据。Vidio服务器要求高传输率和同步,但对分辨率要求相对较低。Picture要求高分辨率。Catalogue要求能处理大量查询并提供对超文本信息系统的链接。客户机程序较为简单,是对以上服务器的集成化的用户界面。客户机/服务器方法可用来实现基于数据仓库的系统,由数据仓库作为服务器提供系统服务。21软件工程各子系统作为客户访问数据仓库,但各子系统还有自己的数据管理功能。服务器与客户间交换数据以执行处理。对于大量的数据交换,可通过高速网络来解决性能问题。客户机/服务器系统多用于具有多个分布式处理器的网络系统。它易于增加一个新的服务器并将其与系统的其他集成在一起。系统中服务器的升级对用户是透明的,且不影响系统的其他部分。22软件工程3)抽象机模型

(abstractmachinemodel)一个体系结构的抽象机模型也称为层次模型。此模型可以建立各个子系统的接口,它把系统组织成一系列的层次,每一层次提供一组服务,定义一个抽象机。每一个抽象机由其下一层的抽象机的代码构成。例如,网络协议的参考模型OSI即为典型的层次模型,而TCP/IP通信协议则为四层的层次模型。23软件工程以太网IPTCPFTP以太网IPTCPFTPFTP协议TCP协议IP协议以太网协议物理连接应用层传输层TCP/IP通信的层次模型24软件工程版本管理系统的例子版本管理系统用于管理对象的版本。为支持配置管理,它使用一个对象管理系统来操作对象的信息存储和服务。对象管理系统又使用数据库系统操作基本数据存储和服务,如事务管理、滚回、恢复和控制存取。数据库管理系统在其实现时又使用操作系统工具和文件堆。25软件工程OperatingSystemDatabaseManage-mentSystemObjectManagementSystemVersionManagementSystem26软件工程抽象机模型支持系统抽象程度递增的系统开发,具有可变更性和可移植性。当一个层次开发出来后,就可以为其上层提供有效的某些服务。如果接口是预定义的,则一个层次可为另一个层次所替换。若一个层次的接口发生变更,仅相邻层次受到影响。层次系统将机器依赖性局部化到它的内部层次上。27软件工程基于复用的层次式体系结构层次式结构中,每一层向其上层提供服务,并利用下层的服务。在层次系统中,内部层次全部被隐藏起来,只有外部层次或某些功能可以为外部可见。层次之间交互的通信协议构成层次间的连接;对层次之间交互的限制构成其拓扑约束。28软件工程用户应用系统基本工具内核过程调用不同元素组合常见的层次结构29软件工程四层式软件体系结构应用软件层特定业务层中间件层系统软件层各个应用的各种变型各个应用系统各个构件库系统

(针对特定领域、特定业务)不依赖平台的低层构件等特定的平台软件:操作系统等30软件工程最高层是应用系统层,此层包含多个应用系统;应用系统可以通过其接口与其他系统操作,还可以通过低层软件提供的服务或对象(如操作系统、特定业务服务)间接地与其他系统交互操作。次高层是“特定业务”层,此层应当包括专门针对不同业务类型的一系列构件库系统。这样的构件库系统向用户提供可复用的使用事例和对象构件,用于开发应用系统。特定业务层的软件建立在中间件之上。31软件工程中间件层位于次高层下面,它为次高层的各个构件库系统提供实用软件类,以及不依赖于平台的服务。最低层是系统软件层,此层包括计算机和网络等基础设施软件,如操作系统、专用的硬件接口软件等。为了确保分层式系统可管理,规定在一个系统内,不能从低层复用高层的构件。32软件工程6.2.2控制模型(Controlmodel)系统构造模型涉及到一个系统如何分解为子系统作为一个整体,必须对各子系统加以控制,使得它们的服务能够在正确的时刻被导向到正确的地方。系统构造模型没有涉及,也不应涉及控制信息,必须按照控制模型组织各子系统,并满足系统构造模型的要求。在体系结构层次上的控制模型应考虑子系统之间的控制流。33软件工程1)集中控制模型

(centralisedcontrolmodel)在集中控制模型中,将一个子系统设计为系统控制器,其职责是管理其他子系统的执行。集中控制模型分为两类:控制子系统顺序执行控制子系统并发执行作为集中控制器的子系统在将控制转交给另一子系统后,该子系统完成它的功能后控制权还要归还给集中控制器子系统。34软件工程(1)调用-返回模型(Call-Returnmodel)此即熟悉的自顶向下的子程序模型。控制始于子程序层次的顶部,通过子程序调用,从层次结构较高层的程序向较低层的程序传递控制信息。程序执行结束将向较高层的父程序返回。这种程序模型仅应用于顺序系统。该模型可以在模块层使用,以控制函数或对象。35软件工程控制的Call-Return模型Routine1.1Routine1.2Routine3.1Routine3.2Routine1Routine2Routine3MainProgram36软件工程在调用-返回系统结构中,每一层都只与上下相邻的两层通信,每一层在利用下层基础服务的条件下,为上层提供服务。这种结构的优点是:提供逐步抽象的编程支持,支持复用及系统升级缺点是:不是所有的系统都适合于建成层次结构,不能提供最佳性能。37软件工程(2)管理器模型(managermodel)这种模型应用于并发系统。模型中有一个系统构件被设计为系统管理器,它控制开始、终止,并协调其他系统进程。一个进程可以是子系统,也可以是模块,它可以与其他进程并行执行。这种模型也可应用于顺序系统。管理例程根据某些状态变量的值调用特定的子系统。38软件工程一个实时系统的集中控制模型SensorprocessesActuatorprocessesComputationprocessesUserInterfaceFaultHandlerSystemcontroller39软件工程位于中央的系统控制器管理一组进程的执行,这些进程管理传感器、传动装置等。根据系统的状态变量,系统控制器决定什么时候进程应该启动或停止。系统控制器负责监测哪些进程产生需要处理的信息,或哪些进程收到需要处理的信息。系统控制器不停地循环,轮流检测传感器和其他进程的事件和状态变化。基于上述功能,有时将此模型称为事件-循环模型。40软件工程2)事件驱动系统(Event-drivensystem)集中控制模型通过一些系统状态变量值决定控制的流向;事件驱动模型则是通过外部生成的事件来驱动系统。事件与简单输入间的区别在于事件的时序存在于事件处理进程控制的外部。一个子系统可能需要存取状态信息来处理这些事件,但这些状态信息并不决定控制的流向。广播模型中断驱动模型41软件工程(1)广播模型(Broadcastmodel)在这种模型中,一个事件向所有的子系统广播,由能够处理此事件的子系统响应它。这种模型的控制策略不嵌入在事件和消息处理器内。子系统决定它需要哪些事件,而事件和消息处理器负责将事件发送给它们。在广播模型中,子系统注册有关特定事件的信息。一旦事件发生,控制将转移到能够处理该事件的子系统。42软件工程对于在网络中跨越不同计算机分布的集成子系统,广播模型十分有效。所有事件可能会广播给所有的子系统,但会消耗大量的处理开销。事件处理器通常还支持点对点通信。事件和消息处理器子系统1子系统2子系统3子系统443软件工程广播模型的优点是演进比较容易。新的子系统可以通过在事件与消息处理器中注册它可以处理的事件来实现集成。任何子系统可以在不知道其他子系统名字或位置的情况下激活那些子系统。实时系统一定是事件驱动的,它要求快速处理外部生成的事件。44软件工程(2)中断驱动模型(Interrupt-drivenmodel)这种模型专用于硬实时处理系统。系统中只有有限的几种中断类型。每一中断都与中断向量中的一个存储位置相关联,该位置中存储了相应中断处理器的入口地址。当系统接收到一个特定类型的中断时,硬件开关立即将控制以间址方式转移到相应的中断处理器,进行相应的中断处理。中断处理器对事件的响应将是启动或停止其他某一进程。45软件工程InterruptsProcess1Handler1Process2Handler2Process3Handler3Process4Handler4Interruptvector这种模型可以嵌入到其他控制模型中使用,用以对事件作出紧急反应。46软件工程6.2.3模块分解

(Modulardecomposition)在设计出一个结构性体系结构后,下一步就是将子系统分解为模块。在系统分解和模块分解之间没有严格的区别。将子系统分解为模块时用到两种模型:

对象模型数据流模型如有可能,应避免并发设计,因为顺序设计在设计、编码、验证和测试都比较容易。47软件工程1)对象模型(Objectmodel)在对象模型中,将系统分解为一组对象。对象具有松散耦合和仔细定义的界面,对象的状态是私有的,对象的操作是基于其状态定义的。对象具有诸如封装、隐蔽、继承等良好的特性。对象必须自己维护其数据的一致性。对象是系统的构件。因此对象分解的焦点在于对象类、对象属性及对象操作。实现时,对象就是从这些类中产生。48软件工程这种体系结构的优点是:将具体的实现部分隐蔽在对象中,使得代码之间的独立性很好,有利于将复杂的系统分解为相互操纵的子任务。缺点是:对象间进行一般的调用时必须知道对方的标识。如果一个对象的标识发生变化,所有显式调用这个对象操作的地方都要修改。对象之间的同步等还缺乏现成的机制。49软件工程Customercustomer#nameaddresscreditperiodPaymentinvoice#dateamountcustomer#Receiptinvoice#dateamountcustomer#Invoiceinvoice#dateamountcustomer#issue()sendReminder()acceptPayment()sendReceipt()50软件工程2)数据流模型(Data-flowmodel)在数据流模型中,将系统分解为一系列功能模块。这种结构包括批处理和管道及过滤器。在体系结构中的每一个成份都有一套输入和输出数据,都依输入-变换-输出的方式工作。进行数据变换的构件叫做过滤器。把数据从一个过滤器的输出导入到另一个过滤器的输入,就叫做管道。51软件工程在系统中,各个过滤器必须是相互独立的,每一个过滤器对它的上游或下游的过滤器的情况是不知道的,也不能做任何假设。如果要求最终的输出结果与各个过滤器的执行次序相关,就是一个数据流方式的体系结构。这种结构的优点是:数据流程设计明确,直接支持复用,系统容易维护和升级,可以进行某些性能分析(如流量、死锁等),容易支持并行计算。52软件工程invoices处理系统的数据流模型ReadissuedinvoicesIdentifypaymentsIssuereceiptsReceiptsFindpaymentsdueIssuepaymentreminderRemindersInvoicesPayments53软件工程6.3特定领域的体系结构前面介绍的体系结构模型都是一般的模型,可应用于各种不同类型的应用中。对于一个特殊的应用领域,还可使用特定于它的体系结构模型,在开发新的系统时可以复用其公共体系结构。这种体系结构模型即为特定领域的体系结构。存在两种特定领域的体系结构模型:类属模型(Genericmodel)

参考模型(Referencemodel)54软件工程6.3.1类属模型类属模型是从许多实际系统中抽象出来的模型,它封装了这些系统的主要特征。例如,在实时系统中,对于不同类型的系统,如数据采集系统、监控系统等,有它们各自的类属模型。又例如,在语言的编译器中包括有词法分析器、语法分析器、语义分析器、代码生成器等,还有在编译过程中建立的符号表、语法树等。存在不同的体系结构模型组织编译器的构件。55软件工程编译器的数据流模型编译器可以使用复合模型实现。编译器用数据流体系结构实现,处理流程按词法分析语法分析语义分析代码生成的顺序执行,但处理共享数据时,使用了当作数据仓库用的符号表。符号表词法分析

语法分析

语义分析

代码生成

56软件工程数据流模型在没有用户交互的批处理环境下执行编译十分有效。但当编译器需要与其他语言处理工具,如编辑器、交互调试器、字体打印机等集成时效果不是很好。此时,编译器可以使用基于数据仓库的模型来组织类属系统的构件。在这种模型中,符号表、语法树等起到中央信息仓库的作用,各种工具或工具件的通信都经过它。此外,有关程序的语法定义、输出格式定义等都从工具中取出,归入到数据仓库中。57软件工程语言处理系统的数据仓库模型语法树词法分析器

语法分析器

语义分析器

字体打印机

编辑器

优化器

代码生成器

语法定义符号表符号表数据仓库58软件工程6.3.2参考模型一般的软件体系结构模型反映的是已有系统的体系结构,而参考模型反映了一大类系统的体系结构。参考模型源于对应用领域的研究,它描述了一个理想化的包含了系统应具有的所有特征的软件体系结构。典型的例子是OSI参考模型。它描述了开放系统互连的标准。如果一个系统遵从这个标准,就可以与其他遵从该标准的系统互连。59软件工程通常,参考模型不能被正式看作是系统实现的方式,而主要使用它作为比较一个应用领域中不同系统之间异同的工具。OSI参考模型是一个七层模型。较低层主要实现物理连接,中间层主要实现数据传输,较高层实现带有语义的应用信息的传输。其他典型的参考模型有关CASE环境的参考模型ECMA,关于软件工厂的参考模型,某些设计模式等。60软件工程OSI参考模型的体系结构应用层表示层对话层传输层网络层数据链路层物理层网络层数据链路层物理层应用层表示层对话层传输层网络层数据链路层物理层通信介质61软件工程6.4分布式系统体系结构所有大型计算机系统现在都是分布式系统。分布式系统的信息处理分布在多个计算机上,而不是只限于单个计算机上。在分布式系统中,系统软件运行于用网络相连的一组松散地集成在一起的处理器上。例如,银行的ATM系统、预定系统、群件(Groupware)系统等。62软件工程6.4.1分布式系统的主要特征资源共享

允许硬件、软件资源共享使用。开放性

是指系统通过非私有资源来扩展自己的能力。分布式系统可包括来自不同厂家的硬件和软件的兼容产品。并发性

在分布式系统中,在网络的不同计算机上可同时运行多个进程,它们在运行期间可以互相通信。可伸缩性

分布式系统是可伸缩的,可以通过增加新的资源来满足对系统的新的需求。63软件工程容错性

具有多台计算机和复制信息的潜能意味着分布式系统能够容忍某些硬件或软件的失效。在大多数系统中,当失效发生时会导致某些服务能力下降,只有当网络失效时才完全丧失其服务能力。透明性

是指对用户隐藏了系统的分布情况。用户可以完全透明地访问系统的资源而不必了解系统资源的分布。不过,在多数情况下,可以让用户了解一些有关系统组织的知识,这有助于用户更好地使用这些资源。64软件工程6.4.2典型的分布式系统的体系结构多处理器体系结构多处理器系统由多个不同的进程组成,这些进程可以在不同的处理器上运行。例如,在实时系统中,采集信息、制订决策、执行控制等进程可以由调度器控制在同一台处理器上运行,而使用多处理器则能够改进系统的性能和弹性。进程分配到哪一台处理器,可以是预先确定的,也可以用分配器控制进行分配。65软件工程多处理器交通控制系统多进程的软件系统不一定是分布式系统。但如果有多个处理器可用,可考虑分布式实现。传感器控制进程控制室显示进程交通灯光控制进程传感器处理器交通流量处理器交通信号控制处理器交通流量传感器和摄像头交通信号灯操作员控制台66软件工程客户机/服务器体系结构在这种体系结构中,一个应用程序被模型化为一组由服务器提供的服务和一组使用这些服务的客户机。客户机需要知道服务器的存在,但通常不知道其他客户机的存在。客户机与服务器是不同的进程。通常我们讨论它们时,把它们当作逻辑进程,就是说,不关心它们物理上放在哪一台计算机上。67软件工程客户机/服务器体系结构逻辑模型,进程与处理器之间不一定是一对一的映射。s1服务器进程客户机进程c1c5c11c12c6c7c10s1网络s2s3s4c8c9c1c2c3c468软件工程客户机/服务器网络中的计算机物理模型,是逻辑模型的具体实现CC1CC2CC3CC4CC5CC6SC2SC1网络c1c2c3,c4c8,c9c10,c11,c12c5,c6,c7s3,s4s1,s2SC2服务器计算机客户机计算机CC169软件工程客户机/服务器的三层结构表示层处理与用户的交互和显示提交给用户的信息。应用处理层实现应用的逻辑。数据管理层定义和操作数据库。在集中式系统中,三层的界限不必分得这样清楚。在分布式系统中必须清楚地给出它们之间的界限,以便将每一层分布到不同的机器上。表示层数据管理层应用处理层70软件工程客户机/服务器的二层结构二层客户机/服务器体系结构有两种形态:瘦客户机模型所有应用处理与数据管理都在服务器上,客户机只负责表示功能。胖客户机模型服务器只负责数据管理,客户机负责应用逻辑与系统用户的交互。应用处理数据管理数据管理服务器

客户机服务器

客户机表示表示应用处理瘦客户机模型胖客户机模型71软件工程电子商务系统常用的三层体系结构数据层数据存储应用逻辑层业务处理、业务流转、系统管理、日志管理、消息管理、权限管理、码表维护、其他等;表示层用户接口;Web服务器(表示层)应用服务器(应用逻辑层)数据库服务器(数据层)ASP\Java源程序解释执行ASP\Java源程序ADO\ODBC采购请求数据库信息批发72软件工程6.4.3分布式对象体系结构分布式系统设计的更通用的方法是去掉客户机与服务器的差别,用分布式对象系统进行设计。在分布式对象体系结构中,对象是基本系统构件。对象提供一组服务,并提供对外这些服务的接口。对象之间不存在客户机与服务器的界限。接受服务者即扮演客户机的角色,提供服务者就是服务器。73软件工程对象可能分布在网络的多台计算机上,它们通过中间件相互通信。这个中间件被看作软件总线,它提供服务实现对象通信和增删。软件总线o1s(o1)o2s(o2)o3s(o3)o4s(o4)o6s(o6)o5s(o5)o7s(o7)o8s(o8)o9s(o9)74软件工程这个中间件叫做对象请求代理,它的作用是在对象之间提供一个无缝的接口。原则上,系统中的对象可以通过不同的程序语言来实现,可以运行于不同的平台上,而它们的名字在系统中可以不为其他对象所知。中间件就像“胶水”一样实现无缝的对象通信。有两种主要的支持分布式对象计算的标准。CORBA(通用对象请求代理体系结构)DCOM(分布式构件对象模型)75软件工程6.5设计模式所谓模式一词来源于城市和建筑领域。美国加州大学环境结构中心研究所所长ChristopherAlexander经过22年对舒适住宅和周边环境进行大量调查和资料收集工作,发现人们对舒适住宅和城市环境存在着共同的认同规律。他把它们归结为253个模式,对每个模式都从Context(模式可适用的环境条件)、Theme或Problem(在特定条件要解决的目标和问题)、6.5.1什么是模式?

76软件工程

Solution(对目标问题求解过程中各种物理关系的记述)等三个侧面进行描述。因此,所谓“模式”是指遵从某种规则或规律反复出现的思维方式或表现。ChristopherAlexander说过:“每一个模式描述了一个在我们周围不断重复发生的问题以及该问题的解决方案的核心。这样,你就能多次使用该方案而不必做重复劳动。”一般来讲,模式是针对某一特定前提的解法。它记述着我们身边频繁发生的某类问题及其基本解77软件工程 法,我们可以反复使用这些解法。对同类问题可以使用同一解法,而不必总是一切从头做起。将模式最早引入软件工程领域的是1991~1992年以“四人帮(GangofFour)”自称的四位软件工程专家,他们在1994年归纳发表了23种设计模式,旨在用模式来统一沟通面向对象方法在分析、设计和实现之间的鸿沟。1995年Gamma等人出版的《设计模式:可复用6.5.2设计模式的概念78软件工程 面向对象软件的基础》对设计模式进行了基本分类,并讨论了一些新的需要研究的模式,引发了模式研究的热潮。设计模式的原则用面向对象方法中的类和对象做个比较。类的设计包括了两部分:属性和方法。对于类的每一个对象,方法都一样,但属性值各不相同。通过类和对象的划分,把运行时不会变化的和会变化的部分分开,并且通过给可以变化的部分赋值,使对象可以工作在更多的环境中。79软件工程类的另一个特点是封装,即把类的功能的声明与实现分开。设计模式也是这样,通过把声明和实现分离,提供了类似的灵活性:一个灵活的设计应可以作为模板来解决一组类似的问题,为此需要把随环境、状态变化的部分和不变化的部分尽可能分离。此外,为便于使用和复用,声明和实现也最好分开。这是类的设计给出的启示。设计模式基本也是遵从这样的方式实现的。80软件工程正是因为设计模式与类的机制很相似,所以,设计模式很适合使用面向对象的方式加以设计与实现。设计模式的运用运用设计模式包括:选择、使用和总结。它们是相互相对独立的三个过程。选择在运用设计模式之前,需要了解所有设计模式解决什么样的问题。因为每一种设计模式是针对特定的问题,或根据特定的情况设计81软件工程

的,它们是针对软件设计时面对的典型问题的成功设计方案。设计模式依照它们所能解决的问题进行了分类,这种分类提供了模式的检索和选择的基础。选择设计模式时需要注意的两个方面:扫描各种设计模式的“意图”栏,根据这些模式的分类,仔细地分析自己的问题应当对应到那几种模式。研究这些模式之间的细微差别。有了几个82软件工程

固定的目标后就可以进行详细的比较,最终选择使用的模式。使用在选择了设计模式之后,考虑如何使用:浏览所选模式,特别注意“适用性”和“效果”两栏,确认它能解决你的问题。仔细研读“结构”、“参与者”、“协作”等三栏,确认你已理解其中的类、对象,以及它们之间的关系。阅读“代码示例”,看看这个模式的代码的83软件工程

具体例子。程序代码能够帮助你学会如何运作设计模式。给模式的参与者一个名字,使它们在应用的环境中有意义。原设计模式中参与者的名字过于抽象,不适合用作应用程序中的名字,因此,建议将其纳入为名字的一部分,使模式的角色在程序中更突出。例如,在文字排版算法中用到Strategy模式,可以选择

SimpleLayoutStrategy

作为类名,还可以选择TeXLayoutStrategy。84软件工程定义类,声明这些类的接口和它们的继承关系,定义有关数据和对象引用的实例变量。并且找出设计模式会影响到哪些既有的类,做出相应的修改。根据设计模式所指明的操作名称来定义你的应用程序中的操作的名字。最好参考应用程序的性质、每个操作的职责和交互来命名,还须注意保持与命名规则的一致。例如,可以用“Create-”这个固定的前置词来称呼Factorymethod。实现设计模式中各个操作的职责和交互。85软件工程在使用设计模式时,注意不能随意使用。当你通过引入间接层次获得灵活性和可变性的同时会使程序更复杂,速度更慢,还会给维护一个个更复杂的系统带来困难。因此,只有当确实需要获得系统的灵活性时,才有必要使用。模式中的“效果”一栏,可以帮助你评估使用模式的得失。总结总结对模式使用的效益,包括使用模式的适合程度和效果。86软件工程使用设计模式时可能对模式做一些小变动,总结这种变动的原因和效果。设计者通过总结所有考虑到的情况、问题以及解决的方法,为日后有效使用模式取得经验,同时可以从中发现系统中可能潜在的问题,发现应用于特定领域的设计模式。设计模式的四个基本要素模式名用于描述模式的名字,说明模式的问题、解决方案和效果。问题

解决说明在何种场合使用模式。要描述使用模式的先决条件和特定设计问题。87软件工程解决方案描述设计的成分、它们之间的相互关系、各自的职责和合作方式。效果

描述模式使用的效果,包括对时间和空间的衡量,以及对系统灵活性、可扩充性、可移植性的影响。设计模式的模板模式名和分类模式名描述了模式的本质。意图说明设计模式做什么?基本原理和意图是什么?它要解决什么特定设计问题?别名

模式的其他名称。88软件工程动机

说明设计问题以及如何用模式中的类、对象来解决该问题的特定情景。适用性

什么情况下可使用该设计模式?该模式可用来改进哪些不良设计?结构

采用UML描述模式中的类,并使用顺序图说明对象间的请求序列和协作关系。参与者设计模式中的类和/或对象以及它们各自的职责。效果

模式怎样支持它的目标?使用模式的效果和所需做的权衡取舍?系统结构的哪些方面可以独立改变?89软件工程实现实现模式时需要知道的一些提示、技术要点及应避免的缺陷,以及是否存在某些特定于实现语言的问题。代码示例说明怎样用C++或SmallTalk

实现该模式的代码片段。已知应用实际系统中发现的模式的例子,每个模式应至少包括两个不同领域的实例。相关模式与这个模式紧密相关的模式有哪些?其间重要的不同之处是什么?这个模式应与哪些其他模式一起使用?90软件工程设计模式的特性灵活性

设计模式应是精巧的解决方法。一般化

设计模式不依赖于某一种特定的系统类型、程序设计语言或应用领域。已验证

设计模式已在某些面向对象系统中实践并已通过测试。简单性

设计模式通常较小,只有几个类。可复用可在设计层次(不是编码层次)应用于所有的系统。面向对象设计模式以面向对象形式出现。91软件工程设计模式的类型依据设计模式工作目的不同,模式可分为创建型模式

(Creationalpattern)与对象的创建有关;结构型模式

(Structuralpattern)处理类和对象的组合,将一组对象组合成一个大的结构,例如复杂的用户界面;行为型模式

(Behavioralpattern)描述类或对象的交互和职责分配,定义对象间的通信和复杂程序中的流控。92软件工程依据设计模式是用于类还是用于对象,模式还可分为类模式和对象模式。类模式处理类与子类之间的关系。这些关系通过继承建立,是静态的。对象模式处理对象之间的关系。这些关系在运行时是可以变化的,具有动态性。创建型类模式将对象的部分创建工作延迟到子类。创建型对象模式则将它延迟到另一个对象中。结构型类模式使用继承机制组合类,结构型对象模式则描述对象的组装方式。93软件工程行为型类模式使用继承机制描述算法和控制流,行为型对象模式则描述一组对象如何协作完成单个对象无法完成的任务。94软件工程目的创建型结构型行为型范围类FactoryMethod(工厂方法)Adapter(适配器)Interpreter(解释器)TemplateMethod(模板方法)对象AbstractFactory(抽象工厂)Builder(生成器)Prototype(原型)Singleton(单件)Adapter(适配器)Bridge(桥接)Composite(组合)Decorator(装饰)Façade(外观)Flyweight(享元)Pxoxy

(代理)ChainofResponsibility(职责链)Command(命令)Iterator

(遍历器)Mediator(中介者)Memento(备忘录)Observer(观察者)State(状态)Stratgy

(策略)Visitor(访问者)95软件工程共享状态备忘录生成器遍历器代理桥接适配器命令复合享元装饰责任链解释器策略状态观察者中介者保存遍历状态枚举所有子女创建组合加职责给对象使用组合命令避免滞后定义遍历访问者定义链增加操作定义语法共享终结符增加操作共享策略共享组合改变皮肤和内脏复杂依赖关系管理创建型模式结构型模式行为型模式96软件工程创建型模式结构型模式行为型模式模板方法工厂方法经常使用原型抽象工厂单件外观动态地配置工厂用工厂方法实现单个实例单个实例策略定义算法步骤97软件工程6.5.3

创建型模式创建型模式描述怎样创建一个对象。它隐藏对象创建的具体细节,使用程序可不依赖具体的对象。因此当增加一个新对象时几乎不需要修改代码。创建型类模式将对象的部分创建工作延迟到子类,创建型对象模式将它延迟到另一对象中。这时,重点从定义固定的行为集合转向定义一个较小的基本行为集合,由这些行为可以组成许多更复杂的行为集合。98软件工程模式的特点封装了系统中使用的类的具体信息;隐藏了这些类的实例如何创建、如何放在一起的(机制)。系统关于这些对象所知道的只有由抽象类定义的接口。创建型类模式有FactoryMethod(工厂方法)。创建型对象模式包括AbstractFactory(抽象工厂)、Builder(生成器)、Prototype(原型)、Singleton(单件)四种模式。99软件工程1.Abstractfactory(抽象工厂)1) 意图以同一个接口建立一整族相关或相互依赖的对象,而不用指明各对象真正所属的具体类。2) 动机例如,在创建可支持多种GUI标准(如Motif和PersentationManager)的工具包时,因为不同的GUI标准会定义出不同外观及行为的“用户界面组件”(widget),如滚动条、按钮、视窗等。为了能够囊括各种GUI标准,应用程序不能把组件写死,不能限制到特定GUI风格的组件类,否则日后很难换成其他GUI风格的组件。100软件工程解决方法是:先定义一个抽象类WidgetFactory(用斜体字区分抽象类),这个类声明了创建各种基本组件的接口,再逐一替各种基本组件定义相对应的抽象类,如ScrollBar、Window等,让它的具体子类来真正实现特定的GUI标准。在WidgetFactory的接口中,可以通过一些操作传递回各种抽象组件类旗下具体创建的对象个体,用户程序可以据此得到组件个体,但它不知道到底涉及了哪些具体类。这样使得用户程序与底层GUI系统之间保持了一种安全距离。101软件工程各GUI标准都有自己的WidgetFactory具体子类,它的操作可以创建出相应的GUI组件。例如,MotifWidgetFactory的CreateScrollBar()操作可以创建并传递回一个Motif风格的滚动条,PMWidgetFactory的CreateScrollBar()则可以创建并传递回一个PresentationManager风格的滚动条。用户程序只需通过WidgetFactory接口,不必知道幕后到底是哪些个类参加工作,就是说,用户程序只针对抽象类的接口编写,而非特定的具体类。

102软件工程ClientPMWindowMotifWindowWindowPMScrollBarMotifScrollBarScrollBar具体类抽象类《create》WidgetFactoryCreateScrollBar()CreateWindow()MotifWidgetFactoryCreateScrollBar()CreateWindow()PMWidgetFactoryCreateScrollBar()CreateWindow()《create》103软件工程classWidgetFactory{//抽象工厂:窗口构件接口public:virtualCreateScrollBar()=0;//创建滚动条

virtualCreateWindow()

=0;//创建窗口};classMotifWidgetFactory:publicWidgetFactory{public:

MotifWidgetFactory(){…实现略…};

CreateScrollBar(){…实现略…};

CreateWindow(){…实现略…};};classPMWidgetFactory:publicWidgetFactory{public:

PMWidgetFactory(){…实现略…};

104软件工程

CreateScrollBar(){…实现略…};

CreateWindow(){…实现略…};};class

ScrollBar{//滚动条抽象类public:

ScrollBar(){};virtualvoidCreateScrollBarInstance(ScrollBar&*)=0;virtualvoiddisplayScrollBar()=0;};classMotifScrollBar:publicScrollBar{//Motif滚动条具体子类public:

MotifScrollBar(){…实现略…};voidCreateScrollBarInstance(MotifScrollBar&*s){105软件工程

MotifWidgetFactory*t;s=t->CreateScrollBar();}};classPMScrollBar:publicScrollBar{//PM滚动条具体子类public:

PMScrollBar(){…实现略…};voidCreateScrollBarInstance(PMScrollBar&*){

PMWidgetFactory*t;s=t->CreateScrollBar();

}};class

Window{//窗口抽象类public:Window(){};106软件工程

virtualvoidCreateWindowInstance(Window&*)=0;};classMotifWindow:publicWindow{//Motif窗口具体子类public:

MotifWindow(){…实现略…};voidCreateWindowInstance(MotifWindow&*s){

MotifWidgetFactory*t;s=t->CreateWindow();}};classPMWindow:publicWindow{//PM窗口具体子类public:

PMWindow(){…实现略…};voidCreateWindowInstance(PMWindow&*){

PMWidgetFactory*t;s=t->CreateWindow();

107软件工程

}};classFactory{Public:

ScrollBar*getScrollBarInstance(inttype){switch(type){case0:MotifScrollBar*s;CreateScrollBarInstance(s);returns;break;case1:PMScrollBar*s;CreateScrollBarInstance(s);returns;break;default:returnNULL;}}108软件工程

Window*getWindowInstance(inttype){

switch(type){case0:MotifWindow*w;CreateWindowInstance(w);returnw->displayWindow();break;case1:PMWindow*w;CreateWindowInstance(w);returnw->displayWindow();default:returnNULL;}}};voidmain(int

argc,char*argv[]){if(argc!=3){

cout<<”errorparameters”<<endl;return;}109软件工程

inttype=atoi(argv[1]),widget=atoi(argv[2]):/*参数type选择GUI标准,widget选择图元*/Factoryfactory;if(widget==0){//图元为滚动条

ScrollBar*s=factory.getScrollBarInstance(type);if(s==NULL){cout<<”errorgettheinstance!”<<end;return;}}else{//否则,图元为窗口

Window*w=factory.getWindowInstance(type);if(w==NULL){cout<<”errorgettheinstance!”<<end;return;}}}

110软件工程每一种GUI标准都有各自的WidgetFactory

的具体子类,其操作会建立适当的GUI组件。例如,MotifWidgetFactory的CreateScrollBar()操作会建立和传送一个Motif式的滚动条,PMWidgetFactory的同一操作则会建立PresentationManager式的滚动条。客户程序只需通过WidgetFactory

的接口,不必知道幕后到底是什么类在运作,就是说,客户程序仅针对抽象类的接口编写,而不是针对特定的具体类。WidgetFactory也规范了与基本窗口组件类之间111软件工程 的依赖关系。例如,通过MotifWidgetFactory

的居中运作,Motif式的滚动条只能与Motif式的按钮、Motif式的窗口搭配使用。3)

适用性

在以下情况下使用抽象工厂模式:当一个系统要独立于它的产品的创建、组合和表达时;当一个系统要由多个产品标准中的一个来配置时;当一整族相关的对象必须一块儿使用,你又得确保不会搭配错误时;当你提供类库,但只想提供接口而不是实现时。

112软件工程ClientProductA2ProductA1AbstractProductAProductB2ProductB1AbstractProductB具体类抽象类《create》AbstractFactoryCreateProductA()CreateProductB()ConcreteFactory1CreateProductA()CreateProductB()ConcreteFactory2CreateProductA()CreateProductB()《create》113软件工程4) 协作在执行时,ConcreteFactory类的实例只有一个,专门针对某种特定的实现标准,建立具体可用的产品对象。 如果想要建立其他标准的产品对象,客户程序就得改用另一种ConcreteFactory。

AbstractFactory将产品对象的建立延迟到它的子类ConcreteFactory。114软件工程2.Builder(生成器)1) 意图

把一个复杂对象的构造与其使用分离开来,将具体建造和控制建造工作分离,使得同一个构建过程可以创建不同的表示。2) 动机

例如,我们希望rtf文件的阅读程序能够将rtf格式转换为其他文件格式:可以转换为纯文本txt格式,也可以输出到doc文件中。问题是:文件格式与转换动作非常多,应当有一个一劳永逸的办法,即使日后有新的文件格式出现,也不必动手修改这个阅读程序。115软件工程一种解决办法是:在rtf阅读程序中设置一个TextConverter对象(它可将rtf转换为其他文件格式)。每当rtf阅读程序读到一个rtf语汇单元时,就会让TextConverter

将其转换为特定格式。TextConverter对象的子类各自负责一种转换。例如,ASCIIConverter

只负责转换文本文字,忽略其他转换请求;TeXConverter

会处理所有请求,尽可能转换成TEX能够表示的文件格式信息;一个TextWidgetConverter

则生成复杂的GUI对象,供使用者浏览和编辑。116软件工程

RTFReaderParseRTF()while(t=getthenexttoken){switcht.Type{Char:builder->ConvertCharacter(t.Char)Font:builder->ConvertFontChange(t.Font)Para:builder->ConvertParagraph()}}TextConverterConvertCharacter(char)ConvertFontChange(Font)ConverterParagraph()ASCIIConverterConvertCharacter(char)GetASCIIText()TeXConverterConvertCharacter(char)ConvertFontChange(Font)ConverterParagraph()GetTeXText()TextWidgetConverterConvertCharacter(char)ConvertFontChange(Font)ConverterParagraph()GetTextWidget()ASCIITextTeXTextTextWidgetbuilderbuilders<<create>><<create>><<create>>117软件工程每一种Converter类都有建立和组装复杂对象的机制,并通过继承包装成抽象接口。阅读程序负责解析rtf文件,与Converter彼此独立。

builder模式统筹处理以上的关系。在模式中称每个转换器为builder,称阅读程序为director。模式将“解释文件格式的运算”与“生成和表示转换后的格式”分离开来。将新的TextConverter类当作RTFReader的子类,即可增加新的转换。3) 时机当想把“建立复杂对象的算法”与对象实现方式分离开来时;118软件工程想让同一个对象生成程序能够产生不同布局形式的对象时。4) 结构forallobjectsinstructure{builder->BuildPart()}DirectorConstruct()BuilderBuildPart()ConcreteBuilderBuildPart()GetResult()Productbuilder《create》119软件工程5) 协作客户程序首先创建Director对象,并将配置设置成想要的Builder对象;Director会在需要建立Product的各种部件时通知Builder;Builder处理Director的命令,将部件一一加到Product中去;最后客户程序从Builder那里取得Product。120软件工程3.FactoryMethod(工厂方法)意图定义一个用于创建对象的接口,但让子类决定实现哪一个类的对象。此模式让一个类将创建对象的过程交给子类来处理。动机举例说明,假设有一个应用程序框架,可以同时显示多个文档。该框架有两个关键角色:Application和Document类,两者都是抽象类,客户程序必须根据自己的需求派生出子类。例如,想设计一个绘图程序,就要定义DrawingApplication和DrawingDocumen类。Application类负责管理Documen,并在需要时121软件工程创建它们,如当用户选择“OpenDocument()”或“NewDocument()”时。因为该创建哪一种特定的Document子类会因应用程序而异,所以Application类无法事先预测DocumentOpen()Close()Save()Revert()ApplicationCreateDocument()NewDocument()OpenDocument()Document*doc=CreateDocument();docs.Add(doc);doc->Open();docs*MyDocumentMyApplicationCreateDocument()<<create>>returnnewMyDocument;122软件工程 应该创建哪一种Document子类。FactoryMethod模式的处理是:将“应该创建哪一种Document子类”的知识封装起来,并与该框架分离。由Application的子类重定义源自Application的抽象操作CreateDocument(),让它传回适当的Document子类。Application的子类的对象自然应知道该产生什么样的Document类型,即使它并不知道确切的类名是什么。称这个CreateDocument()为FactoryMethod,因为它负责“制造”对象。123软件工程3) 适用性在下列情况下可以使用工厂方法模式:当一个类无法指明想创建的对象所属的类时。当一个类希望由它的子类来指定想创建的对象类型时。当类将创建对象的职责下放给多个辅助用途的子类,并且又希望将“交付给那些子类”的知识集中在一起的时候。结构见下页协作

Creator的子类必须定义factorymethod的实现,以传回需要的ConcreteProduct对象。124软件工程CreatorFactoryMethod()AnOperation()……product=FactoryMethid();……ConcreteProductConcreteCreatorFactoryMethod()<<create>>returnnewConcreteProduct;Product125软件工程4.Singleton(单件)意图一个类只有一个实例并提供一个访问它的全局访问点。该实例应在系统生存期中都存在。动机例如,通常情况下,用户可以对应用系统进行配置,并将配置信息保存在配置文件中,应用系统在启动时首先将配置文件加载到内存中,这些内存配置信息应该有且仅有一份。下面的代码应用了单件模式以保证Configure类只能有一个实例。这样,Configure类的使用者无法定义该类的多个实例,否则会产生编译错误。126软件工程classConfigure{pritected:Configure(){};//构造函数public:StaticConfigure*Instance();//全局对象public:

int

getConfigureData(){returndata;}//读取函数

int

setConfigureDate(int

m_data)//存储函数

{data=m_data;returndata;}private:staticConfigure*_instance;

intdata;//配置信息};

127软件工程Configure::

instance=NULL;Configure*Configure::Instance(){if(_instance==NULL){

_instance=newConfigure();

//加载配置文件并设置内存配置信息,此处省略

}return

instance;};

voidmain(){Configure*t=NULL; t=Instance();

intd=t->GetConfigureData();

//获取配置信息后进行其它工作,此处省略};128软件工程如何保证类只有一个实例。而且存取方便。采用静态对象可以实现全局存取。单件模式让类自己负责,让它自己管理这唯一的实例,让它确保不会生出第二个实例,也可以提供方便的手段来存取这个实例。SingletonstaticInstance()SingletonOperation()getSingletonData()staticuniqueInstancesingletonDatareturnuniqueInstance129软件工程单件类被声明为classSin

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论