第章面向对象设计与实现.pptx
- 文档编号:18705009
- 上传时间:2023-10-13
- 格式:PPTX
- 页数:123
- 大小:914.38KB
第章面向对象设计与实现.pptx
《第章面向对象设计与实现.pptx》由会员分享,可在线阅读,更多相关《第章面向对象设计与实现.pptx(123页珍藏版)》请在冰点文库上搜索。
第11章面向对象设计与实现,面向对象设计模型构件级设计确定并发性使用设计模式面向对象详细设计数据存储与持久性设计部署设计与构件图案例分析,面向对象设计概述,面向对象分析和面向对象设计之间有着密切的衔接关系,从面向对象分析到面向对象设计是一个逐步精化模型的过程。
设计模型是系统需求和系统之间的桥梁,是设计构造本身的一个重要部分。
而面向对象设计模型是对系统中包含的对象或对象类,以及它们之间的不同类型关系的描述。
领域类模型包模型,11.1设计模型,面向对象设计模型是对系统中包含的对象或对象类,以及它们之间的不同类型关系的描述。
面向对象的设计两类设计模型:
静态模型:
通过系统对象类及其之间的关系来描述系统的静态结构。
在UML中常用类图、用例图、构件图、包图等描述系统中元素的关系。
动态模型:
描述系统的动态结构和系统对象之间的交互。
在UML中常用时序图、协作图、状态图、活动图等来描述系统的行为。
域类模型领域分析确定域类包模型:
用包图表示,域类模型,包图,对象接口描述,接口设计中应该避免涉及接口的具体表示正确的方式是将具体的接口实现方法隐藏起来,只提供对象操作来访问对象和修改数据接口可以用UML中的类图形式来描述UML的格式标记“interface”中必须包含名字部分,图书馆系统中借书者的接口,interfaceborrowerpublicvoidborrower(intborrowerid,intbookid);publicvoidsetborrower(intborrowerid);publicvoidaddload(Loadloaditem);publicvoidgetload();publicvoidgetnoload();publicvoidremoveload();publicvoidwrite();publicvoidread();/borrower,11.2构件级设计,构件级设计定义了数据结构、算法、接口特征和分配给每个软件构件的通信机制。
每个构件的类定义或者处理叙述都转化为一种详细设计。
设计采用图形或基于文本的形式来详细说明内部的数据结构、局部接口细节和处理逻辑。
设计符号包括UML图和一些辅助表示。
通过一系列结构化编程结构来说明程序的设计。
构件类,构件是计算机软件中的一个模块化的构造块在OMGUML规范中将构件定义为“系统中某一定型化的、可配置的和可替换的部件,该部件封装了实现并暴露一系列接口”。
面向对象的观点:
构件中的每一个类都被详细阐述,包括所有的属性和与其实现相关的操作。
从分析模型开始,详细描述分析类(对于构件而言该类与问题域相关)和基础类(对于构件而言该类为问题域提供了支持性服务)。
传统观点:
模块控制构件,协调问题域中所有其他构件的调用;问题域构件,完成部分或全部用户的需求;基础设施构件,负责完成问题域中所需要相关处理的功能。
构件级设计步骤,步骤1:
标识出所有与问题域相对应的设计类步骤2:
确定所有与基础设施相对应的设计类步骤3:
细化所有不能作为复用构件的设计类在类或构件的协作时说明消息的细节为每一个构件确定适当的接口细化属性并且定义相应的数据类型和数据结构详细描述每个操作中的处理流步骤4:
说明持久性数据源(数据库和文件)并确定管理数据源所需要的类步骤5:
开发并且细化类或构件的行为表示步骤6:
细化部署图以提供额外的实现细节步骤7:
考虑每一个构件级设计表示,并且时刻考虑其他选择,基于类的构件设计原则,开关原则(TheOpen-ClosedPrinciple,OCP):
模块应该对外延具有开放性,对修改具有封闭性。
替换原则(SubsitutionPrinciple,SP):
子类可以替换它们的基类。
依赖倒置原则(DependencyInversionPrinciple,DIP):
依赖于抽象、而非具体实现接口分离原则(InterfaceSegregationPrinciple,ISP):
多个用户专用接口比一个通用接口要好。
发布复用等价性原则(ReleaseReuseEquivalencyPrinciple,REP):
复用的粒度就是发布的粒度。
共同封装原则(CommonClosurePrinciple,CCP):
一同变更的类应该和在一起。
共同复用原则(CommonReusePrinciple,CRP):
不能一起复用的类不能被分到一组。
11.3确定并发性,系统设计的一个重要目标就是识别必须是并发获得的那些对象和具有互斥获得的对象。
可以将具有互斥获得的对象叠加在单线程控制或任务中。
状态机模型可以帮助我们识别并发性。
如果两个对象在不交互的情况下,在同一时刻可以接受事件,它们就是内在并发的。
如果事件不同步,我们就不能将这两个对象叠加在单线程控制中。
不能将两个内部并发的构件实现成一个独立的硬件单元,ATM并发实例分析,在ATM机系统中,当银行校验账户或处理银行交易时,ATM机就会闲置。
如果中心计算机直接控制ATM机,可以把ATM对象与银行交易对象合并成单项任务。
将每一个并发子系统分配给一个硬件单元,可以是通用处理器或者是特定的部件。
ATM机本身比较简单,处理的活动基本都是用户界面和一些本地处理,因此单CPU就已经足够。
对于中心计算机,由于要接受多个ATM机的请求,并将请求分配给相应的银行计算机,因此需要多个CPU来解决瓶颈问题。
银行计算机执行数据处理操作,并包含相对简单的数据库应用,可根据所需的吞吐率和可靠性来选择数据库版本。
硬件和软件的选择,对于硬件和软件的选择,我们必须确定要用硬件和软件分别实现哪些子系统。
ATM机应用没有迫切的性能需求,通用的计算机就可以满足了。
系统设计必须将不同软件子系统的任务分配给处理器。
给处理器分配任务要考虑特定动作、通信限制和计算限制等。
ATM机系统没有任何通信和计算限制的问题。
如果ATM必须要有自主性,当通信网络出现故障时还可以运行,那么它就必须要有自己的CPU和程序设计。
确定物理部件之间的配置和连接形式,确定物理部件之间的配置和连接形式,包括连接拓扑、重复部件和通信。
比如,进程间的通信调用连接的单个操作系统内部的任务,这种调用要比同一个程序中的子程序要慢得多,对于时间要求比较严格的时候是不实用的。
简单的做法是合并任务,运用子程序来建立连接。
ATM机系统中,多个ATM客户机连接到中心计算机,然后路由到相应的银行计算机。
拓扑结构是星型的,中心计算机来仲裁通信。
11.4使用设计模式,有经验的软件开发者建立了既有通用原则又有惯用方案的指令系统来指导他们编制软件。
如果以结构化形式对这些问题、解决方案和命名进行描述使其系统化,那么这些原则和习惯用法就可以称为模式。
基于职责设计对象(GeneralResponsibilityAssignmentSoftwarePatterns,GRASP)信息专家、创建者、控制器、高内聚、低耦合、多态、纯虚构、间接性和防止变异GoF(GangofFour)模式23种设计模式,其中基本的有适配器、工厂、单实例类、策略、组合、外观和观察者等模式,基于职责的设计,职责驱动设计也即基于职责的设计。
在设计中软件对象具有职责,即对其所作所为进行抽象。
UML把职责定义为“类元的契约或义务”。
就对象的角色而言,职责与对象的义务和行为相关。
职责分为以下两种类型:
对象的行为职责包括:
自身执行一些行为,如创建对象或计算初始化其他对象中的动作控制和协调其他对象中的活动对象的认知职责包括:
对私有封装数据的认知对相关对象的认知对其能够导出或计算的事物得认知职责的粒度会影响职责到类和方法的转换,GRASP,职责不同于方法,职责是一种抽象,而方法实现了职责。
绘制UML交互图时,就是在决定职责的分配。
通过GRASP中的基本原则来指导如果分配职责给一个对象。
五种基本的GRASP模式:
创建者模式信息专家模式控制器模式低耦合模式高内聚模式,职责与方法,创建者模式,问题:
一个对象由谁(哪个对象)创建?
指导原则是:
将创建一个对象A的职责分配给对象B的条件是B“包含”或组成聚集了A、B记录A、B紧密地使用A或者B具有A初始化数据并且在创建A时会将这些数据传递给A。
简而言之,就是一个对象要由拥有或者使用其信息的、与其有密切关系的另一个已存在的对象创建。
例如在POS机系统中的Sale对象是由那个对象类创建?
对于对象Sale由谁创建,分析一下领域模型就会发现,可以认为Register是记录Sale的类。
因此Register对象是创建Sale对象的合理选择。
POS机系统中谁创建Sale对象,信息专家模式,信息专家(通常称为专家)模式是最基本的职责分配原则之一。
创建者是对象的行为职责,而信息专家常常指的是对象的认知职责。
指导原则是:
给对象分配职责时,应该把职责分配给具有完成该职责所需要信息的那个类。
例如在POS机系统中,销售的总额该如果确定?
决定总额的一些元素应该是属于哪些对象的信息?
按照信息专家的建议,这里应当寻找具有确定总额所需信息的那个对象类。
分析领域模型和设计模型得到,要计算总额应该知道销售的所有SalesLineItem实例及其小计之和。
Sale实例包含了上述信息。
为了确定商品的小计,这里需要SalesLineItem.quantity、和ProductDescription.price。
SalesLineItem知道其数量和与其关联的ProductDescription。
计算销售总额,控制器模式,根据MVS(ModelViewSeparation)原则,UI对象不应当包含应用逻辑或业务逻辑。
应该把UI层的操作或者请求委派给一个协调者,由协调者把任务转发给领域层的领域对象。
控制器就是这样一个协调者。
例如在POS机系统中,enterItem和endSale这样的系统事件,应使用谁作为控制器?
指导原则是:
控制器是UI层之上的第一个对象,它负责接收和处理系统操作消息。
控制器的选择原则是:
代表全部“系统”、“根对象”、运行软件的设备或主要的子系统(如,外观控制器);代表发生系统操作的用例场景(如,会话控制器)。
在用例场景中发生的系统事件通常命名为Handler、Coordinator或Session。
对于用同一用例场景的所有系统事件使用相同的控制器类。
控制器类,低耦合模式,低耦合模式是一个评价模式。
低耦合原则适用于软件开发的很多方面,它是构件软件最重要的目标之一。
指导原则是:
分配职责以使耦合保持在较低的水平。
在真实世界领域中,Register记录了Payment,所以创建者模式建议将Register作为创建Payment的候选者。
Register实例会把addPayment消息发送给Sale,并把新的Payment作为参数传递给它。
这种职责分配使Register类和Payment类之间产生了耦合,即Register类要知道Payment类。
高耦合问题,低耦合解决方案,高内聚模式,高内聚模式是一个评价模式。
内聚是软件设计中的一种基本品质,内聚可以非正式地用于度量软件元素操作在功能上的相关程度,也可以用于度量软件元素完成的工作量。
指导原则是:
分配职责可保持较高的内聚性。
低内聚问题,高内聚解决方案,11.5面向对象详细设计,面向对象详细设计的目的就是不断精化设计类领域模型也称为概念模型、领域对象模型和分析对象模型。
领域模型的精化对类图和交互图的精化起了至关重要的作用,也是设计个良好系统的关键。
使用泛化、特化、关联类、时间间隔、组合和包等概念精化领域模型。
一模型精化
(1)泛化和特化,泛化是在多个概念中识别共性和定义超类(普遍概念)与子类(具体概念)关系的活动。
例如在POS机系统中CashPayment,CreditPayment和ChequePayment。
在领域中识别父类和子类是一个有价值的活动,这样可以使我们对概念有更概括、精炼和抽象的描述。
POS机系统中Payment,
(2)定义概念超类和子类,概念超类的定义较子类的定义更为概括或包含范围更广。
例如,在POS机系统中,考虑超类Payment和它的子类。
将概念类划分为子类的动机有:
子类有额外的有意义的属性;子类有额外的有意义的关联;子类概念的操作、处理、反应或使用的方式不同于其超类或其他子类,而这些方式是我们所关注的;子类概念表示了一个活动体,其行为与超类或者其他子类不同,而这些行为是我们所关注的。
泛化和定义概念超类的动机:
潜在的概念子类表示的是相似概念的不同变体;子类满足100%准则(即概念超类的定义必须100%适用于子类,子类必须100%与超类一致。
);所有子类都具有相同的属性,可以将其解析出来并在超类中表达;所有子类都具有相同的关联,可以将其解析出来并与超类关联。
Payment类层次划分,(3)关联类,原则:
在领域模型中,如果类A可能同时有多个相同的属性B,则不要将属性B置于A之中。
应该将属性B放在另一个类C中,并且将其与类A关联。
这样就得出一个关联类C。
在POS机系统中,授权服务给每个商店分配一个商业ID,商店发送授权服务的支付授权请求需要商业ID标识商店,商店对于每个服务有不同的商业ID。
Store可能有多个merchantID值,所以将merchantID作为Store的属性是不正确的。
同理,放入AuthorizationService中也不正确。
可以用一个关联类ServiceContract来拥有属性merchantID关联类的增加具有原则:
有某个属性与关联相关;关联类的实例具有依赖于关联的生命期;两个概念之间有多对多关联,并且存在与关联自身相关的信息。
关联类,(4)聚合关系和组合关系,聚合是UML中的是UML中的一种模糊关联,其不明确的暗示了整体和部分关系。
组合也称组成聚合,是一种强的整体部分聚合关系,并且在某些模型中具有效用。
组合关系意味着:
在某一时刻,部分的一个实例只属于一个组成实例;部分必须总是属于组成;组成要负责创建和删除部分,可以自己创建和删除部分也可以和其它对象协作进行创建和删除部分;组成被销毁,其部分必须要销毁。
组合关系的识别准则是:
部分的生命期在组成的生命期之内,部分的创建饿删除依赖于整体;在物理或者逻辑组装上,有明确的整体部分关系;组成的某些属性会传递给部分;对组成的操作可能传递给部分。
识别和显示组合关系,好处:
有利于澄清部分对整体的依赖的领域约束;有助于使用GRASP创建者模式识别创建者;对整体的复制、拷贝这些操作经常会传递给部分。
在POS机系统中,SalesLineItems可以被视为Sale的组成部分。
ProductCatalog是ProductDescriptions的一个组成。
组合关系,(5)时间间隔,例如,POS机系统在初始设计时,SalesLineItems与ProductDescriptions关联,记录了销售项的价格。
在精化过程中,需要关注与信息、合同等相关的时间间隔问题。
如果SalesLineItems从ProductDescriptions取得当前价格,当价格改变时,以前的销售将指向新的价格,这很显然是不正确的。
需要区别销售发生时的历史价格和当前价格。
基于信息需求,可以采用两种方法对此问题解决:
一是可以在ProductDescriptions中保存当前价格,仅将销售发生时的价格写入SalesLineItem;二是将一组ProductPrices与ProductDescriptions关联,每个ProductPrices关联适用的时间间隔。
区别历史价格和当前价格,(6)组织领域模型,将领域模型划分成包结构时,将满足下述条件的元素放在一起:
在同一个主题领域,概念或目标密切相关的元素;在同一个类层次结构中的关系;参与同一个用例的元素;有很强的关联性的元素。
例如,在POS机系统领域模型中包的结构,POS机系统领域模型,包嵌套,二逻辑架构的精化设计,在逻辑架构精化设计中主要更细化各层内部元素、层与层之间关系和分层架构中一些模式的应用。
遵循模型-视图-控制器(MVC)三层模型。
在精化逻辑模型时首先要进一步指出个系统层之间、包之间的关系。
可以用依赖线来表达包或者包内类型之间的耦合。
依赖线可以由一个包发出例如在POS机系统中从Sale包指向POSRuleEngineFacade类,从Domain包指向Log4J包。
简单包和子系统,外观和控制器,模型-视图分离和“向上”通信,包设计准则,包在水平和垂直划分上的功能性内聚由一族接口组成的包正式包和聚集不稳定类的包职责越多的包越需要稳定将不相关的类型分离出去使用工厂模式减少对具体包的依赖,分离不相关的类型,具体包的依赖,工厂模式减少对具体包的依赖,精化的交互图,在交互图中,领域模型指出了需要设计的软件对象,设计模型中的设计类是以领域模型的类为基础的。
在顺序图和协作图精化设计中,一些类直接来自前面的分析模型中的类,还有一些针对软件系统的更好的实现虚构出来的。
例如设计makeNewSale操作。
要处理一次新的销售,首先必须创建软件对象Sale。
根据控制器模式我们还需要设计一个转发makeNewSale请求的对象Register。
Register是记录Sale的类。
又根据创建者模式得出应该由Register创建Sale。
在销售过程中必须设计一个集合来存储一系列的商品,所有由Sale对象创建了记录所有将来会添加的集合SalesLineItem实例。
三设计问题,精化设计本地缓存处理异常处理,类精化设计,输入商品,结束销售,获取总价,处理支付,计算找零,本地缓存处理,当远程服务访问失败时(比如产品数据库暂时无法访问),需要保障交易正常进行。
解决的方法是使用由servicesFactory工厂创建的Adapter对象,实现对服务位置的防止变异。
例如,可以提供远程服务的本地部分复制,实现从远程到本地的容错。
本地产品信息数据库将缓存最常用的一小部分产品信息,等重新连接时将在本地存储库存的更新。
为了满足重新连接远程服务的质量场景,对这些服务使用智能代理对象,在每次服务调用时都要测试远程服务是否激活,并且在远程服务激活时进行重新定向,实现从远程服务访问失败中恢复。
数据恢复,为了实现从远程数据库访问失败中恢复的可能性,我们建议使用ProductDescription对象的本地缓存,以文件形式存放在本地硬盘中。
在试图访问远程服务之前,应该总是首先在本地缓存中查找产品信息。
使用适配器和工厂模式能够间接地实现这一特性:
ServiceFactory总是返回本地产品信息服务的适配器;本地产品适配器并不会真正地适配其他构件,它将负责实现本地服务;使用实际的远程产品服务适配器的引用来初始化本地服务;如果本地服务在缓存中找到数据,就将数据返回;否则,将请求转发给外部服务。
两级客户端缓存,在内存中的ProductCatalog对象保存着从产品信息服务中读取的一些ProductDescription对象的内存集合,例如Java的HashMap。
依据本地可用内存的大小,可以调整该集合的大小。
本地产品服务可以维护一个较大的持久化缓存,例如基于硬盘文件存储,用于维护一定数量的产品信息。
该持久化缓存对于容错很重要,即使POS机应用程序崩溃,内存中的ProductCatalog对象丢失,但持久化缓存依然有效。
通过ServicesFactory工厂返回一个本地服务。
本地服务获取了对外部服务的适配器的引用。
系统首先从本地获取产品信息,如果存在则直接读取。
若果本地没有,则从本地文件中读取产品数据信息。
如果本地文件也没有该产品信息,则系统从外部服务器上读取信息。
异常处理,由于产品价格经常变动,缓存价格信息会导致数据失效。
解决的方案是增加远程服务操作,来查询当日更新的数据。
LocalProducts对象定期地查询并更新它的缓存。
如果这样做,将LocalProducts对象设计为拥有控制线程的主动对象。
线程休眠一段时间,唤醒后读取数据,再次休眠,如此反复。
对线程的run可以视为异步消息,用“active”表示LocalProducts对象为主动对象,其运行于自身线程之上。
异常处理,采用对象缓存文件的方案可以提高系统效率,但是本地缓存没有产品信息时访问外部产品服务失败时,系统如何处理?
通知故障的最直接的方法是抛出一个异常。
当访问外部产品数据库失败时,持久化子系统可能抛出异常。
常用的异常处理模式称为“转换异常”模式。
转换异常模式的原则是:
在一个子系统中,避免直接抛出来自较低层子系统或服务的异常。
应该将较低层的异常转换成在本层子系统中有意义的异常。
较高层的异常包裹较低层的异常并添加一些信息,使得该异常在较高层的子系统语境中有意义。
持久化子系统捕获一个特定的SQLException异常,并且抛出一个新的包含SQLException异常的DBUnavailableException异常。
较高层的DBProductAdapter作为逻辑子系统的代表,可以捕获较低层的DBUnavailableException异常,并且抛出一个新的ProductInfoUnavailableException异常,而新的异常包裹了DBUnavailableException。
两个模式来处理异常:
集中错误日志(CentralizedErrorLogging)和错误会话(ErrorDialog)。
集中错误日志模式的原则是:
使用单实例类访问的集中错误日志对象,所有的异常都向它报告。
异常设计,如果产品不在本地产品服务的缓存中,则本地产品服务将与外部服务的适配器进行协作。
本地产品服务将ProductDescription对象缓存为串行化对象。
如果实际的外部服务从数据库改为新的WebService,则只需改动远程服务的工厂配置。
考虑到与DBProductsAdapter的协作,适配器需要与对象-关系映射持久化子系统交互。
支付实现,结束销售后就是获取总额的操作。
由控制器发出getTotal()操作并要求返回总额tot。
总额计算得出后就可以进行makePayment()操作。
最后是计算找零的系统操作,将Sale对象与Payment对象相结合。
容错处理,系统的使用过程是首先尝试本地服务,如果没有命中,然后进行尝试外部服务。
但这种方案并不是对所有服务都适用,例如账务服务过程中的记录销售,希望快速实时地追踪商店和终端的活动。
代理(Proxy)模式是解决这个问题较好的方案。
代理模式的变体称为远程代理(RemoteProxy)模式。
代理模式的另一种变体称为重定向代理(RedirectionProxy)模式,也称为容错代理(FailoverProxy)。
代理模式的一般结构,重定向代理,代理模式的基本原则是:
通过代理对象增加一层间接性,代理对象实现与subject对象相同的接口,并且负责控制和增强对主体对象的访问。
重定向代理:
向重定向代理发送postSale消息,将其视为实际的外部账务服务;如果重定向代理通过适配器与外部服务通信失败,则将postSale消息重定向到本地服务。
本地服务将Sale保存在本地,当账务服务激活时重新发给它。
抽象工厂模式,POS机系统中,系统需要与各种各样的设备进行工作,包括显示器、票据打印机、现金抽屉、扫描仪等等。
这些设备许多都存在工业标准和已经定义好的标准的面向对象接口。
例如,UnifiedPOS是为POS机设备定义了接口的工业标准的UML模型。
使用工厂模式从系统属性中读取需要加载的类集,并返回基于其接口的实例。
设备驱动能够与JavaPOS接口进行适配,因此可以看作是适配器对象。
它们可以作为代理对象,控制和增强对物理设备访问的本地代理。
抽象工厂模式的基本原则,定义一个工厂接口(抽象工厂),为每一族要创建的事物定义一个具体的工厂类。
或者定义实际的抽象类来实现工厂接口,为扩展该抽象类的具体工厂提供公共服务。
抽象工厂模式的一种变体是创建一个抽象工厂,使用单实例类(Singleton)模式访问它,读取系统属性以决定创建哪个子类工厂,然后返回对应的子系统实例。
基本思想,抽象类工厂设计,精化的类图,类图和对象图是设计阶段的主要制品顺序图和协作图中的消息映射为类图中的方法,交互消息的对象映射为类的对象,每个消息的交互实现映射
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 面向 对象 设计 实现