1.47k likes | 1.88k Views
GRASP: 设计带职责的对象. 徐迎晓 xuyingxiao@126.com 复旦大学软件学院. 设计带职责的对象. 交互设计和职责分配的质量决定系统的质量 可维护性 可理解性 可重用性 可扩展性 好的面向对象设计原则可用于交互图设计和职责分配 — GRASP 模 式. GRASP :通用职责分配软件模式 General Responsibility Assignment Software Patterns 将职责分配给对象的基本原则. GRASP: 设计带职责的对象. 五个 GRASP 模式 应用 G RASP 实现 Process Sale 用例
E N D
GRASP:设计带职责的对象 徐迎晓 xuyingxiao@126.com 复旦大学软件学院
设计带职责的对象 • 交互设计和职责分配的质量决定系统的质量 • 可维护性 • 可理解性 • 可重用性 • 可扩展性 • 好的面向对象设计原则可用于交互图设计和职责分配—GRASP模式
GRASP:通用职责分配软件模式 • General Responsibility Assignment Software Patterns • 将职责分配给对象的基本原则
GRASP:设计带职责的对象 • 五个GRASP模式 • 应用GRASP实现Process Sale用例 • 可见性设计 • 类图设计
五个GRASP模式 • .Low Coupling • .High Cohesion • .Controller • .Creator • .Information Expert
模式:Low Coupling • Problem:如何降低依赖、减少改变的影响,增加重用性? • Solution:分配职责时使耦合低
原理: • 耦合表明两个类之间连接的强度,一个类是否依靠其他类 • A具有低耦合,则A不依赖很多其他的类 • 高耦合带来的问题 • 其他类改变则可能自己也必须改变 • 单独(无其他类时)难以理解 • 由于需要很多其他类,难以重用
举例 • we have a need to create a Payment instance and associate it with the Sale. • 谁来创建Payment 实例?
两种都假定Sale和Payment之间有关联,register创建则增加关联,不好两种都假定Sale和Payment之间有关联,register创建则增加关联,不好
讨论 • 低藕合模式常与专家、高内聚一起使用 • 是基本目标,所有设计决策中都要考虑 • 中等层度的藕合是正常和必需的(对象之间需要连接以便协作) • 优点:不受其他组件变化的影响,易于理解,易于重用
类X和类Y之间常见的藕合 • X有属性引用Y的实例 • X对象调用Y对象的服务 • X的方法引用Y的实例(参数,局部变量,返回值) • X是Y直接或间接子类 • Y是接口,X实现Y
But 对稳定元素的藕合和普遍的元素藕合很少会有问题 • 如类库
五个GRASP模式 • .Low Coupling • .High Cohesion • .Controller • .Creator • .Information Expert
模式:Hign Cohesion • Problem:如何使复杂性可管理? • Solution:分配职责时使内聚度高
内聚:类的职责如何紧密关联 • 类或子系统等若职责紧密关联,且没有大量的工作,则具有高内聚度 • 高内聚则方法的数量相对较少 • 若task is large,则与其他对象协作 • 低内聚说明类做了很多无关的事情,或做了太多的事情 • 低内聚的问题:难以理解,重用,维护,易受变化的影响
不独立使用,而是与专家、低藕合模式一起使用不独立使用,而是与专家、低藕合模式一起使用 • 评估所有设计决策的一个准则 • Register做很多系统操作,下图哪个好?
RDB-RPC-Interface class • responsible for interacting with relational databases and for handling remote procedure calls • (two vastly different functional areas)
RDBInterface class • completely responsible for interacting with relational databases. • hundreds or thousands of methods(all related) • A lot of supporting code
RDBInterface class • Only partially responsible for interacting with relational databases • interacts with a dozen other classes related to RDB access
Company class • completely responsible for (a) knowing its employees and (b) knowing its financial information. • total number of public methods is small • the amount of supporting code is small
可低内聚的场合 • grouping of responsibilities or code into one class or component to simplify maintenance by one person • 只有1,2个SQL专家,对OO不熟 • software architect may decide to group all the SQL statements into one class, RDBOperations
可低内聚的场合2 • distributed server objects • less remote calls, and better performance. • 远程服务器对象要fewer and larger, less cohesive,为很多操作提供接口 • 远程操作粗粒度,以便一次remote operation call可以做或请求更多的工作 • Example 1: remote object with three fine-grained operations setName, setSalary, and setHireDate • Example 2: one remote operation setData which receives a set of data • Which is better?
五个GRASP模式 • .Low Coupling • .High Cohesion • .Controller • .Creator • .Information Expert
模式:Controller • Problem:谁负责处理系统输入事件? • Solution:将处理系统输入事件的职责分配给代表以下的类: • 代表整个系统、设备或子系统-外观Controller(facade controller) • 代表整个业务过程或组织(facade controller) • 代表现实世界中可能执行该任务的角色(role controller) • 代表系统事件发生的用例场景,(use-case or session controller)
Problem: • The UI & domain layers should be loosely coupled • Which object should coordinate msgs between the UI and other domain objects? • Solution (advice): • Assign responsibility to an object representing.. • The ‘system’ or a ‘root’ object (Store, Bank) • A device/subsystem (AccountingSystem, BankATM) • A use case scenario (GameHandler) • ‘Single channel of communication between layers’
“window,” “applet,” “widget,” “view,” and “document”不是控制器,而是将事件发往控制器 • 系统操作在设计时通常交给控制器
可供选择的 • 代表整个系统、设备或子系统 • Register, POSSystem • 代表整个业务过程或组织 • Store • 代表现实世界中可能执行该任务的角色 • Cashier • 代表系统事件发生的用例场景 • ProcessSaleHandler
讨论 • 大多数系统接受外部输入事件(GUI,传感器信号,…) • 一个用例中所有系统事件用一个控制器处理,不同用例用不同控制器 • 控制器通常将将需要做的工作委托给其他对象,自己并不做很多工作
优点 • 业务处理由业务对象完成,而不是把图形界面作为控制器,这样可重用性高 • 将控制器的职责委托给各个领域类,支持逻辑重用 • 但要防止控制器过于臃肿 • 可用多个控制器 • 可用角色控制器或用例控制器,而不是facade controller
五个GRASP模式 • .Low Coupling • .High Cohesion • .Controller • .Creator • .Information Expert
模式:Creator • Problem:谁负责创建新的对象? • Solution: • 如果满足以下条件之一,则将创建类A的实例的职责分配给类B • B聚合A对象 • B包含A对象 B contains A objects. • B记录A对象(前三个最常用) • B紧密使用A对象 • B具有创建A对象时需要传入的初始化数据 • B是A的Creator • 如果有多个类满足条件,优先选择聚合或包含关系
Name: • Creator • Problem: • Who creates an A? • Solution: (this can be viewed as advice) • Assign class B the responsibility to create an instance of class A if one of these is true (the more the better): • B "contains" or compositely aggregates A. • B records A. • B closely uses A. • B has the initializing data for A.
举例 • 谁负责创建SalesLineltem对象?
讨论 • 低耦合 • 对依赖的维护少 • 可重用性高 • 简明,封装 • But 若出于性能考虑使用回收的实例,或根据外部的值从一组类似的类中挑选一个创建实例 • 建议将创建工作交给helper class----Factory,而不使用本模式
五个GRASP模式 • .Low Coupling • .High Cohesion • .Controller • .Creator • .Information Expert
模式:Information Expert • Problem OOD中分配职责最基本的原则是什么? • Solution将职责分配给Information Expert(拥有完成该职责所需要信息的类)