单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,GRASP:,基于职责设计对象,目标,学习使用面向对象设计的5个GRASP原那么或模式,UML与设计原那么,最关键的软件开发工具是受过良好设计原那么训练的思维而不是UML或其他任何技术。,学习GRAPS和根本GoF设计模式是本书的关键目标。,职责和职责驱动设计,考虑系统中各个对象的职责、角色和协作,以此来驱动设计的过程,称为职责驱动的设计。,职责:类元,(Classifier),的职责或义务。,职责的类型:,行为,(doing),认知,(knowing),职责和职责驱动设计,行为职责:,自身执行的一些行为,如创立对象或计算,初始化其他的对象,控制和协调其他对象中的活动,认知职责,对私有封装数据的认知,对相关对象的认知,对其能够导出或计算的事物的认知,GRASP,General Responsibility Assignment Software Patterns,使用职责进行OO设计的根本原那么,帮助你理解根本对象设计,以一种系统的,合理的,可以解释的方式来推导设计。,职责、,GRASP,和,UML,图之间的关系,交互图与分配职责密切相关:绘制交互图的过程就是职责分配的过程。,什么是模式,(pattern),在面向对象的设计中,模式是对问题和解决方案的已命名描述。,模式的关键元素:,名称,问题,解决方案,对于特定的问题,可以应用许多原那么模式为对象分配职责,模式陈述的不是新的设计思想,而是将已有的,经过验证的知识、惯用法和原那么汇编起来。,用到的领域模型,低耦合,问题,:,怎样降低依赖性,减少变化带来的影响,提高复用性。,解决方案,:,使得耦合尽可能低的方式分配职责。,低耦合,(cont),什么是耦合,耦合是某元素和其他元素之间的连接、感知和依赖程度的度量。,低耦合意味着对其他元素的依赖程度低。,高耦合导致的问题,:,局部的变化影响整体,难以被单独理解,难以重用,低耦合,:Example,假设我们需要创立Payment的实例,将他关联到Sale。哪个类应该担当这个职责?,Payment,Register,Sale,低耦合,:Example(cont),:,Register,makePayment(),p:Payment,1:create(),:,Sale,2:addPayment(p),:Register,makePayment(),:,Sale,1:makePayment(),:,Payment,1.1:create(),低耦合,:Discussion,低耦合是在设计决策期间必须牢记的原那么,是应该不断被考虑的根本目标。,通常会与其他模式一起考虑,如“信息专家或“高内聚,低耦合,:Discussion(cont),没有绝对的度量标准来衡量耦合程度的上下,低耦合的极端例子是没有耦合:对象间没有或极少通信。,不可取,因为这个例子违反了对象技术的根本原那么:系统由相互连接的对象组成,对象之间通过消息通信。,耦合度过低产生不良设计,其中会使用一些缺乏内聚性、膨胀、复杂的对象来完成所有工作。,对象间适度的耦合对于一个优良的面向对象系统是非常重要的。,低耦合,:Discussion(cont),优点,:,不受其它构件变化的影响,易于单独理解,便于重用,低耦合与信息隐藏,低耦合:耦合的类型,TypeX 与TypeY有关系,TypeX具有TypeY的属性,TypeX直接或间接引用了TypeY,比方局部变量,参数,或对象调用对象TypeY的效劳。,TypeX是 TypeY的子类.,TypeY是接口,TypeA实现了该接口,低耦合:限制,高耦合对于稳定和普遍使用的元素不是问题.比方,J2EE应用能够平安地将自己与Java库(java.util)耦合,因为Java库是稳定、普遍使用的。,高内聚,问题,怎样保持对象是有重点的、可理解的、可管理的,并且能够支持低耦合,解决方案,分配职责以保持较高的内聚性。,内聚:对元素职责的相关性和集中度的度量,内聚性低的类要做许多不相关的工作,导致以下问题:,难以理解,难以复用,难以维护,经常受到变化的影响,例如低内聚,例如高内聚,内聚程度的一些场景,非常低的内聚:由一个单独的类负责完全不同功能领域中的大量事务,低内聚:由一个类单独负责一个功能性领域内的复杂事务,高内聚:由一个类负责一个功能性领域内的复杂事务,并与其它类协作完成任务。,适度内聚:类同时负责几个轻量级的领域,这些领域中的概念与该类相关,但彼此之间没有关系。,内聚与耦合的关系,低内聚通常导致高耦合。,可以接受低内聚的例外,将一组职责或代码放入一个类或构件中,以使维护人员能方便地对其进行维护。,为了提高分布式对象的效率。,优点,能够更加轻松、清楚地理解设计,简化了维护和改进工作,通常支持低耦合,提高复用性,创立者,问题某类的新实例应该由谁来创立。,解决方案如果以下的条件之一为真时,将创立类A的实例的职责分配给B,B包含或聚集A,B具有A的初始化数据。,创立者例如,组合关系创立者,可以通过寻找具有初始化数据的类来确定创立者:SalePayment,与低耦合模式相关,可以认为是低耦合模式在创立对象时的一个应用。,创立者,对象的创立通常具有相当的复杂性,最好的方法是把创立职责委派给工厂(抽象或具体)类。,优点,支持低耦合,相关模式,低耦合,具体工厂和抽象工厂,整体-局部组合模式,信息专家,(Information Expert),问题:,给对象分配职责的根本原那么是什么?,解决方案:,将职责分配给信息专家,他拥有实现这个类所必需的信息,信息专家,(Information Expert),在我们的系统中,谁应该负责计算销售的合计,?,Sale,date,time,SalesLineItem,quantity,ProductDescription,description,price,UPC,Contains,1.*,*,Described-by,信息专家,(Information Expert),为了计算合计需要哪些信息,?,SalesLineItem,与,Sale,关联,.,而合计可以从,SalesLineItem,的小计算出。,因此,Sale,是信息专家,结束了吗,?,信息专家,(Information Expert)(cont),谁负责计算,SalesLineItem,的小计,?,需要的信息,:,SalesLineItem.quantity,和相关的,ProductSpecification.price,根据信息专家模式,应该是,SalesLineItem,负责计算,SalesLineItem,的小计,类,职责,Sale,知道销售合计,SalesLineItem,知道明细小计,ProductSpecification,知道产品单价,信息专家,(Information Expert)(cont),信息专家,(Information Expert):,讨论,信息专家模式是对现实的模拟,DIY:Do It Yourself,信息专家,(Information Expert):,优点,保证了封装性,对象使用他们自己的信息来完成职责。,支持低耦合,使得系统更为健壮,更易于维护,行为分布在拥有所需信息的类中,提倡定义内聚性更强的“轻量级类,这样的类易于理解和维护。,通常支持高内聚,信息专家,(Information Expert):,限制,在有些场合,由于高内聚和低耦合的要求,信息专家模式并不适用。,比方,谁应该将Sale存入DB?,控制器,问题:,系统事件应该由谁来处理?,解决方案:,将系统事件分配给下面的对象:,代表整个“系统、“根对象 的类。,代表用例场景的类,该事件就是场景中发生的一个事件(use-case controller),对于同一用例场景的所有系统事件使用相同的控制器类。,可以防止在UI层处理业务逻辑,控制器,(cont),系统事件,由外部产生的高层的事件,系统事件不是,UI,事件,不是像,Window/View,这样的对象。,UI,通过,UI,事件接受并组合为一个系统事件,将其委派给控制器完成。,由系统操作来执行,系统事件,系统事件,控制器,:Example,在行为分析的过程中比方系统顺序图,系统操作被识别出来,并赋给 System对象。,然而,这并不是说该事件将由名为System的对象处理。,究竟谁处理这个事件是在设计时引入的控制器对象时分配的。,System,endSale(),enterItem(),makePayment(),.,控制器,:Example(cont),谁来处理登录商品的事件?,由系统本身来处理,:,Register,由用例处理器来处理,:,ProcessSaleHandler,如何选择由其他因素决定,:,耦合,内聚,控制器,:Example(cont),确定系统事件应该分配给一个还是多个控制器,第一类控制器:,Fa,ade Controller,表示整个系统,例,:Register,RetailInformationSystem,Switch,Router,NetworkInterfaceCard etc.,适用于下面情况,只有较少的系统事件,第二类控制器:,Use Case Controller,某个特定用例的所有事件操作定义在同一个用例控制器中。,适用于:,不将操作别离将会违背耦合和内聚的原那么例如:臃肿的控制器,拥有跨越不同子系统的大量事件。,实例,public class EnterItemAction extends Action,public ActionForward execute(ActionMapping,mapping,,,ActionForm,form.),Repository repository=.;,Register register=repository.getRegister();,String txtId=(SaleForm)form).getItemID();,String txtQty=(SaleForm)form).getQuantity();,ItemID id=Transformer.toItemID(txtID);,int qty=Transformer.toInt(txtQty);,register.enterItem(id,qty);,控制器,:,优点,增加了可复用的构件和插拔的潜力。,是将表示层和业务层别离的方法,能够把握用例的状态,保证系统操作是以一种合法的顺序发生,控制器,:,优点,用户界面对象,(windows,applets),和表示层不应该处理系统事件。,处理系统事件是领域对象的职责,:,SaleJFrame,1:makeLineItem(),onEnterItem(),:,Sale,:,SaleJFrame,1:enterItem(),onEnterItem(),:,Register,:,Sale,2:makeLineItem(),相关模式,命令模式,外观模式,层,纯虚构,