通用职责分配软件模式(GRASP)
8--通用职责分配软件模式

南昌航空大学计算机学院
如何处理基于类型的选择?
基于类型的选择。条件的变更是编程中的一个基 本主题。如果程序中用if-then-else或case语 句来设计条件逻辑,那么当一个新的变更出现时, 程序需要修改case逻辑。这种方法使得采用新的 变更来扩展程序很困难,因为程序中往往需要修 改多个地方—条件逻辑存在的任何地方。
使用同一个控制者类处理同一个用况中的所有的 事件
南昌航空大学计算机学院
控制者模式优点 增加软件构件的可重用性 理解用例的状态
南昌航空大学计算机学院
GRASP模式
续
专家 创建者 高聚合度 低耦合度 控制者
前5个GRASP(General Responsibility Assignment Software Patterns)模式
南昌航空大学计算机学院
高聚合度的优点 增加了设计的清晰性和易于理解 简化了软件的升级和维护工作 通常能够支持低耦合度 细粒度、高相关的功能模块还为日后可能的软件 重用提供了支持
南昌航空大学计算机学院
五、控制者 将处理系统事件消息的职责分派给代表下列事物 的类:
代表整个“系统”的类 代表整个企业或组织的类 代表真实世界中参与职责的主动对象类 代表一个用况中所有事件的人工处理者类
南昌航空大学计算机学院
一、专家模式 Sale的总额
南昌航空大学计算机学院
类 Sale SalesLineItem ProductSpecification
职责 知道销售项总额 知道销售项记录子金额 知道商品价格
按照专家模式能够得出这样的设计:一个软件对 象所执行的操作通常是这个软件对象在现实世界 中所代表的事物所能进行的操作。
南昌航空大学计算机学院
J2EE项目实训UML及设计模式——第8章 通用职责分配软件模式(GRASP)(第3部分)

第8章通用职责分配软件模式(GRASP)(第3/4部分)1.1通用职责分配软件模式中的五个基本模式(第2部分)1.1.1GRASP中的高内聚模式1、什么是满足高内聚模式的系统设计(1)高内聚模式能够使应用系统中的各个模块(功能、类)能够各尽其能而又能够充分合作也就是对于需求分析人员所描述的应用系统中的各个功能需求,设计人员可以合理地把它分配给各个模块(功能、类)来共同完成,而不是由一个或几个包揽所有功能的超级类独立地完成。
因为设计人员在应用高内聚模式时,能够充分地考虑和协调系统中的各个类的职责之间的相关程度和集中程度。
(2)而对于该系统中的某一个模块(功能、类),具有自己高度相关的职责即该职责中的几个任务是高度相关的,同时每一个模块(功能、类)都决不去完成与自己无关职责的任务。
通常一个具有高内聚的类,具有相对较少的成员方法和紧密相关的功能实现;同时它并不完成太多的任务,当需要实现的目标任务过大或者相对复杂时,可以通过和其它的对象进行协作来达到。
2、什么是内聚以及低内聚的设计后果(1)系统组成元素的内聚性从对象设计的角度类看,系统组成元素(模块、类等)的内聚性是一个元素的职责被关联和被关注的强弱尺度;如果一个系统组成元素具有很多内聚(紧密相关)的职责,而且只完成有限的功能,每一个模块(功能、类)都决不去完成与自己无关职责的任务;那这个系统组成元素就是高度内聚的。
(2)一个具有较低内聚性的系统组成元素会导致以下问题出现难于理解和难于重用完成一个具体的职责的实现代码分散到不同的类模块中,导致代码的阅读人员需要遍历各个有关的类代码,才能最后明白具体的含义;同时在该类被重用时,还必须携带其它相关联的辅助类代码。
难于维护,并且系统脆弱,常常受到变化带来的困扰由于完成一个具体的职责的实现代码分散到不同的类模块中,因此,当其中的某个类发生了变化,将会波及各个相关的依赖的类,而导致这些依赖的类也需要被动地进行修改。
浅谈对象职责分配模式(GRASP)对软件系统编程实践的指导意义

浅谈对象职责分配模式(GRASP)对软件系统编程实践的指导意义1、通过程序代码示例说明“对象职责分配模式GRASP”对具体编程实践有什么指导意义GRASP模式(General Responsibility Assignment Software Patterns 通用职责分配软件模式)是面向对象设计中的基本设计模式,它们描述了对象设计和职责分配的基本原则——也就是说,它指导我们1)如何把现实世界的业务功能抽象成对象2)如何决定一个系统有多少对象3)每个对象都包括什么职责对上面的这些问题,GRASP模式给出了最基本的指导原则。
GRASP模式表达了对象设计中职责分配的基本原则,它能够帮助我们理解基本的对象设计技术,并且用一种系统的、可推理的、可说明的方式来应用设计理论——GRASP是学习使用GOF 代码设计模式的基础。
下面谈谈GRASP中主要模式——信息专家模式:(1)信息专家模式(Information Expert)------应该将职责分配给信息专家1)问题对象(类)设计和职责分配的一般原则是什么?2)解决方案——“做事应该找懂行的专家来完成!”我们设计对象(类)的时候,如果某个类拥有完成某个职责所需要的所有信息,那么这个职责就应该分配给这个类来实现。
这时,这个类就是相对于这个职责的信息专家。
3)代码示例用例1——管理员创建题库(把题条加入题库),再细化一下:管理员创建题库(把题条加入题库):如果题库中已经存在所给的题条,则退出,否则加入题条。
这样就存在3个对象:管理员用户User,题条SubjectItem,题库SubjectLibrary,2个职责:判断(新加入的题条是否与题库某题条相等),加入(题条的加入)。
这2个职责究竟应该由哪个对象执行?我们使用Information Expert模式来分析。
●判断2个题条是否相等,只要判断题条的ID属性(或其它属性)是否相等就可以了。
题条的ID是属于题条的,所以对它的操作应该放在题条SubjectItem里。
UML复习总结

1.UML(unified modeling language): 统一建模语言是创建描绘软件系统结构和设计蓝图的标准语言。
它用于指定、构造、记录软件系统的工件并使之可视化。
~ 的基本组成部分:包括 UML 的静态、动态、包和注释等部分。
~ 的构建块包含基本的成分、关系和关系图。
基本成分包括结构、行为、分组和注释成分。
2.RUP(rational unified process):统一开发过程是一种过程框架,有助于使用创建和部署用UML设计的软件。
~生命周期分为四个阶段:起始阶段、细化阶段、构造阶段、转换3.软件开发生命周期(SDLC)是一个规范的、系统的软件开发方法。
可分为六个阶段:可行性分析、需求分析和规范说明、设计、编码、测试、维护。
软件的开发方法:瀑布方法、原型方法、螺旋方法、双赢螺旋方法、增量方法。
在设计阶段,有两种~:①面向功能方法以模块为中心,注重软件的功能。
②面向对象(OO)方法支持重用、数据封装、以及继承、抽象和多态性等概念。
4.面向对象分析和设计(OOAD)是指根据对象、类、封装、继承、多态、抽象和动态邦定来分析需求以及设计软件系统。
5.软件系统的各个视图:①用例视图:表示系统为客户提供的功能②设计~:侧重于系统的静态和动态表示③实施~:表示软件系统中组成系统所需的各个文件和组件④部署~:表示将执行软件系统和硬件的组合关系。
6.四种建模技术:①需求建模:包括使用用例关系图描述需求。
②静态~:包括使用类、对象和复合结构关系图来描述软件系统的静态成分③动态~:包括使用以下关系图来描述动态成分的行为:活动关系图、状态机关系图、通信关系图、序列关系图、交互概览图、时序关系图④架构~:描述软件系统的内部结构如何构成:包关系图、主件关系图、部署关系图7.需求管理是一种持续的系统化方法。
~的四个阶段:需求收集、~分析与协商、~规格化、~验证。
需求分析指将需求分类和组织为功能性需求和非功能性需求的过程。
跟我学J2EE 系统构架和设计模式——软件系统详细设计阶段中的“对象职责分配模式(GRASP)”(第1部分)

1.1跟我学J2EE 系统构架和设计模式——软件系统详细设计阶段中的“对象职责分配模式(GRASP)”(第1部分)详细设计阶段包括:模块设计、数据库设计和界面设计。
下面,仅就详细设计中的模块设计部分,讨论与模块设计工作中相关的设计模式应用的有关问题。
在面向对象的方法中,详细设计阶段的一个十分重要的问题,是进行类设计。
类设计直接对应于实现设计,它的设计质量直接影响着软件的质量,所以这个阶段是十分重要的。
这就给我们提出了一个问题,类是如何确定的,如何合理的规划类,这就要给我们提出一些原则,或者是一些模式。
1.1.1模块设计与设计模式的应用1、系统在设计和开发时就应该考虑以后可能的变化(1)用户需求在客观上是不断地变化的在模块设计阶段,最关键的问题是,用户需求是变化的,我们的设计如何“拥抱变化”和“适应变化”呢?(2)需求分析并不能解决一切问题我们经常听到人们在抱怨,一个项目已经通过了交付测试,担投运以后用户又提出了新的需求,这时就面临这样一个问题,修改一段代码就会需要几百个相关代码跟着改变,因此升级就变成几乎不可能的事情,于是,开发者抱怨说,用户为什么当初不提出这些新的需求呢?而用户抱怨说,随着时代的变化当初怎么可能预料到现在的需求呢?最后的结果,恐怕只能是一个,那就是这个系统被弃之不用!其实,这个巨大的损失错在开发者,但却不恰当的由用户来承担了。
(3)比较困惑的事情1)如果我们试图发现事情怎样变化,那我们将永远停留在分析阶段。
2)如果我们编写的软件能面向未来,那将永远处在设计阶段。
因为,我们的时间和预算不允许我们面向未来设计软件。
过分的分析和过分的设计,事实上被称之为“分析瘫痪”。
2、我们如何“拥抱变化”和“适应变化”(1)应该遵守的几个原则1)针对接口编程而不是针对实现编程。
2)优先使用对象组合,而不是类的继承。
3)考虑我们的设计哪些是可变的,注意,不是考虑什么会迫使我们的设计改变,而是考虑要素变化的时候,不会引起重新设计。
通用职责分配模式(GRASP)之创建者模式

通用职责分配模式(GRASP)之创建者模式Creator创建者模式当分析清楚客户需求并设计出用例模型以后,当分析清楚客户业务环境制作出领域模型以后,当综合用例模型、领域模型设计出类和它们的方法以后,当就在一切都准备就绪只欠东风的关键时刻,一个对象发出了撕心裂肺的怒吼——谁来创建我一个对象,不管拥有多么强大的功能,不管进行了多么精巧的设计,如果不能被创建,就如同韩信不能做将军,孙膑不能当军师,勾践不能回越国,刘备不能得荆州,一切一切的雄才武略都如废纸一张。
既然“创建”对于对象如此重要,我们就来好好探讨一下GRASP 中关于对象创建的问题。
创建者(Creator)当我们完成了用例模型、领域模型、对象分析的设计,初步完成了对象设计和职责分配的工作后,开始进一步细化的时候,一个我们不得不考虑的问题就摆在我们的面前——谁来创建这些对象?也许现在的你会觉得好笑,这也是问题吗?在软件实际开发过程中,谁需要使用某个对象,就去创建它就行了,有什么好讨论的。
但是,我不得不说的是,如果你只是漫不经心地想要随意开发一套软件系统,仅仅是完成自己工作而已,你完全不用考虑创建对象的问题。
然而如果你希望开发一套高质量的、低耦合的、封装性和复用性高的软件系统,你必须得认真考虑这个问题。
为什么呢?因为系统中如果一个对象A创建另一个对象B,那么对象A就必将与对象B耦合。
我们可以想像,如果在你的系统中,对于对象B,你也去创建,我也去创建,大家都去创建,对象B势必与许多对象发生耦合,耦合度将大大提高;但如果对象B可以都由对象A 来创建,然后由对象A向其它需要对象B的对象提供对象B,即其它对象需要使用对象B的时候都向对象A索要,那么整个系统对对象B 的耦合将会大大降低,同时对象A和B也可以形成一个封装的、可复用的独立系统,则这个软件系统的设计质量势必提高。
所以,对象创建的问题不可不察。
那么为了降低系统耦合,提高系统的清晰度、封装性和可复用性,应该有一些通用的原则,以用于对象职责分配中,关于“创建对象”这类职责的分配。
Ch17-GRASP基于职责设计对象ppt课件
职责的粒度
职责的粒度会影响职责到类和方法的转换。
大粒度职责 具有数百个和方法。
小粒度职责可能只是一个方法。
例如: “提供访问关系数据库”的职责可能涉及一个子系统中的200 个类和数千个方法。 “创建Sale”职责可能仅涉及一个类中的一个方法。
Controller
精选版课件ppt20
20
Controller
精选版课件ppt21
21
模式名:控制器
Controller
问题:在UI层之上首先接收和协调(控制)系统操作的对象是 什么?
解决方案:将接收或处理系统事件消息的职责分派给代表下 列事务的类:
代表全部“系统”或“根对象”,如MonopolyGame对 象
模式名:信息专家(或专家)
问题:给对象分配职责的基本原则是什么?
解决方案(建议):将职责分配给具有完成该职责所需信 息的那个类
精选版课件ppt16
16
Information Expert
why Expert is a useful (Low Coupling)
精选版课件ppt17
17
QuestiLoownC:oWuplihngy Board over Dog?
24
High Cohesion
模式名:高内聚 问题:怎样使对象保持有内聚、可理解和可管理, 同时具有支持低耦合的附加作用? 解决方案:职责分配应保持高内聚,依此来评估备 选方案。
精选版课件ppt25
25
Creator
在对象设计中应用GRASP
S ale tim e
对象设计和职责分配的设计模式(GRASP)
设计模式Gof设计模式GRASP (职责分配原则)Expert (信息专家)信息专家模式是面向对象设计的最基本原则,是我们平时使用最多,应该跟我们的思想融为一体的原则。
也就是说,我们设计对象(类)的时候,如果某个类拥有完成某个职责所需要的所有信息,那么这个职责就应该分配给这个类来实现。
这时,这个类就是相对于这个职责的信息专家。
例如:常见的网上商店里的购物车(ShopCar),需要让每种商品(SKU)只在购物车内出现一次,购买相同商品,只需要更新商品的数量即可。
如下图:针对这个问题需要权衡的是,比较商品是否相同的方法需要放到那里类里来实现呢分析业务得知需要根据商品的编号(SKUID)来唯一区分商品,而商品编号是唯一存在于商品类里的,所以根据信息专家模式,应该把比较商品是否相同的方法放在商品类里。
(创造者)实际应用中,符合下列任一条件的时候,都应该由类A来创建类B,这时A是B的创建者:a.A是B的聚合b.A是B的容器c.A持有初始化B的信息(数据)d.A记录B的实例e.A频繁使用B如果一个类创建了另一个类,那么这两个类之间就有了耦合,也可以说产生了依赖关系。
依赖或耦合本身是没有错误的,但是它们带来的问题就是在以后的维护中会产生连锁反应,而必要的耦合是逃不掉的,我们能做的就是正确地创建耦合关系,不要随便建立类之间的依赖关系,那么该如何去做呢就是要遵守创建者模式规定的基本原则,凡是不符合以上条件的情况,都不能随便用A创建B。
例如:因为订单(Order)是商品(SKU)的容器,所以应该由订单来创建商品。
如下图:这里因为订单是商品的容器,也只有订单持有初始化商品的信息,所以这个耦合关系是正确的且没办法避免的,所以由订单来创建商品。
coupling (低耦合)低耦合模式的意思就是要我们尽可能地减少类之间的连接。
其作用非常重要:a.低耦合降低了因一个类的变化而影响其他类的范围。
b.低耦合使类更容易理解,因为类会变得简单,更内聚。
通用职责分配模式(GRASP)之低耦合
通用职责分配模式(GRASP)之低耦合(Low Coupling)在GRASP中的创建者模式、信息专家模式的最终目的都是降低耦合。
低耦合这个词大家已经耳熟能详,在spring、MVC、设计模式的书籍中都提到低耦合、高内聚,已经成为软件设计质量的标准之一。
什么是低耦合?耦合就是对某元素与其它元素之间的连接、感知和依赖的量度。
这里所说的元素,即可以是功能、对象(类),也可以指系统、子系统、模块。
假如一个元素A 去连接元素B,或者通过自己的方法可以感知B,或者当B不存在的时候就不能正常工作,那么就说元素A与元素B耦合。
耦合带来的问题是,当元素B发生变更或不存在时,都将影响元素A的正常工作,影响系统的可维护性和易变更性。
同时元素A只能工作于元素B存在的环境中,这也降低了元素A的可复用性。
正因为耦合的种种弊端,我们在软件设计的时候努力追求“低耦合”。
低耦合就是要求在我们的软件系统中,某元素不要过度依赖于其它元素。
请注意这里的“过度”二字。
系统中低耦合不能过度,比如说我们设计一个类可以不与JDK耦合,这可能吗?除非你不是设计的Java程序。
再比如我设计了一个类,它不与我的系统中的任何类发生耦合。
如果有这样一个类,那么它必然是低内聚(关于内聚的问题我随后讨论)。
耦合与内聚常常是一个矛盾的两个方面。
最佳的方案就是寻找一个合适的中间点。
哪些是耦合呢?1.元素B是元素A的属性,或者元素A引用了元素B的实例(这包括元素A调用的某个方法,其参数中包含元素B)。
2.元素A调用了元素B的方法。
3.元素A直接或间接成为元素B的子类。
4.元素A是接口B的实现。
幸运的是,目前已经有大量的框架帮助我们降低我们系统的耦合度。
比如,使用struts 我们可以应用MVC模型,使页面展现与业务逻辑分离,做到了页面展现与业务逻辑的低耦合。
当我们的页面展现需要变更时,我们只需要修改我们的页面,而不影响我们的业务逻辑;同样,我们的业务逻辑需要变更的时候,我们只需要修改我们的java程序,与我们的页面无关。
第7章 GRASP模式
高耦合度的问题: 其他类的改变会迫使这个类改变其自身的 局部定义。 如果不联系其他类,难以孤立地理解它。 难以重用,因为要使用这个类需要它所依 赖的类同时存在。
内聚和耦合:阴和阳
低劣的内聚常常导致低劣的耦合,它们相互牵 制。 在少数情况下,接受低内聚。 例如:为使一个人对系统的维护变得简单,把 所有的SQL语句作为一组加入到一个类中,这 样方便SQL专家在一个地方工作。
4.控制器模式
解决方案:将处理系统事件消息的职责分 派给代表下列事物的类: 代表整个“系统”的类(外观控制器)。 表示一个发生系统事件的用例场景,通常 用“<用例名>处理器”的方式命名(用例 控制器)。
当需要创建类A的实例时,由哪个类来创建 ?
5.创建者模式
告诉我们:当符合以下几种条件或之一时,可 以说类B是类A的创建者: 类B聚合类A的对象; 类B包含类A的对象; 类B记录类A对象的实例; 类B密切使用类A的对象; 类B将初始化的数据,传递给类A的实例。
通用职责分配软件模式
模式:给出问题和解决方案,并赋予其名称 ,称为模式。
由模式名、解决的问题、解决方案组成。 Grasp模式:以模式的形式描述了对象设计和职 责分配的基本原则。ຫໍສະໝຸດ 五种Grasp模式:
信息专家模式 高内聚模式 低耦合模式 控制器模式 创建者模式 以上,给出了为对象分配职责的原则。
我们想设计一个绘图程序要支持可以画不同类型的图形我们定义一个抽象类shape矩形rectangle圆形round分别继承这个抽象类并重写overrideshape类里的draw方法这样我们就可以使用同样的接口shape抽象类绘制出不同的图形
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
General Responsibility Assignment Software Patterns 通用职责分配软件模式
模式名称 描述(问题/解决方案)
信息专家模式Information Expert 问题:对象设计和职责分配的一般原则是什么? 解决方案:将职责分配给拥有履行一个职责所必需信息的类--即信息专家。
(也就是将职责分配给一个类,这个类必须拥有履行这个职责所需要的信息。
)
创建者模式Creator 问题:谁应该负责产生类的实例(对应于GoF 设计模式系列里的
“工厂模式”)
解决方案:如果符合下面的一个或多个条件,则将创建类A 实例
的职责分配给类B.
.类B 聚合类A 的对象。
.类B 包含类A 的对象。
.类B 记录类A 对象的实例。
.类B 密切使用类A 的对象。
.类B 初始化数据并在创建类A 的实例时传递给类A (类B 是创建
类A 实例的一个专家)。
在以上情况下,类B 是类A 对象的创建者。
控制器模式 Controller 问题:谁处理一个系统事件?
解决方案:当类代表下列一种情况时,为它分配处理系统事件消
息的职责。
.代表整个系统、设备或子系统(外观控制器)。
.代表系统事件发生的用例场景(用例或回话控制器)。
低耦合Low Coupling
问题:如何支持低依赖性以及增加重用性?
解决方案:分配职责时使(不必要的)耦合保持为最低。
高内聚High Cohesion
问题:如何让复杂性可管理? 解决方案:分配职责时使内聚保持为最高。
多态模式Polymorphism 问题:当行为随类型变化而变化时谁来负责处理这些变化? 解决方案:当类型变化导致另一个行为或导致行为变化时,应用多态操作将行为的职责分配到引起行为变化的类型。
纯虚构模式Pure Fabrication 问题:当不想破坏高内聚和低耦合的设计原则时,谁来负责处理
这些变化?
解决方案:将一组高内聚的职责分配给一个虚构的或处理方便的“行为”类,它并不是问题域中的概念,而是虚构的事务,以达
到支持高内聚、低耦合和重用的目的。
中介模式Indirection 问题:如何分配职责以避免直接耦合? 解决方案:分配职责给中间对象以协调组件或服务之间的操作,使得它们不直接耦合。
受保护变化模问题:如何分配职责给对象、子系统和系统,使得这些元素中的
式Protected Variations 变化或不稳定的点不会对其他元素产生不利影响?
解决方案:找出预计有变化或不稳定的元素,为其创建稳定的“接
口”而分配职责。