GRASP:Designing Objects with Responsibilities
阅读书上第17章
outputs of object Design
- UML 交互图、类图、包图
- UI草图和原型
- 数据库模型
- 报表的草图和原型
Responsibility-Driven Design
- UML把职责定义为类元的契约或义务
- 对象的行为职责
- 自身执行一些行为,如创建对象或计算
- 初始化其他对象中的动作
- 控制和协调其他对象中的动作
- 对象的认知职责
- 对私有封装数据的认知
- 对相关对象的认知
- 对其能够导出或计算的事物的认知
- 准则:
- 领域模型描述了领域对象的属性和关联,因此通常产生与“认知”相关的职责
- 大职责具有数百个类和方法,小职责可能只有2个方法
GRASP:
- General Responsibility Assignment Software Patterns
- 绘制交互图是考虑将职责实现为方法的时机
-
模式:以结构化形式对这些问题、解决方法和命名进行描述使其系统化,那么这些原则和习惯用法称为模式
- Creator:谁应该负责创建类的实例
- 如果以下条件之一为真,将创建A的实例的职责分配给类B
- B包含或组成聚集了A
- B记录了A
- B直接使用A
- B具有A的初始化数据
- 好处:
- 支持 low coupling,减少维护的依赖性和增加重用的可能性
- 准则:
- 封装的容器和记录类是创建其所容纳和事物的很好的选择
- Information Expert:如果给定键值,谁知道对象的相关信息
- 把职责分配给具有完成该职责所需信息的那个类
- 好处:
- 信息封装,支持低耦合
- 鼓励链接使用更多易于理解和维护的轻量级类定义
- Low Coupling:如何减少因变化产生的影响
- 分配职责以使(不必要的)耦合保持在较低的水平
- coupling:元素与其他元素的连接、感知及依赖的程度的度量
- 在面向对象语言中,以下情况X有对Y的耦合
- X有Y实例/Y类的属性
- X对象调用Y对象的函数
- X有一个方法涉及到Y实例/Y类,如Y的参数或者局部变量或X方法返回一个Y实例
- X是Y的直接/间接子类,子类和超类之间有很强的耦合性
- Y是接口,X是实现
- 好处
- 不会被其他组件的改变所影响
- 便于理解
- 易于复用
- 高耦合本身不是问题所在,而是和不稳定的元素之间的耦合
- Controller:在UI层上的哪个对象应该首先从UI层接收该消息
- 控制器:UI层外第一个负责接收并处理系统操作信息的对象
- 把职责分配给能代表下列选择之一的对象:
- 外观控制器:代表全部“系统”、“根对象”、运行软件的设备或主要的子系统,外观控制器的所有变形
- 用例控制器:代表发生系统操作的用例场景
- 准则
- 控制器应当把需要完成的工作委派给其他对象。控制器只是协调或控制这些活动,本身并不完成大量工作
- 概念
- entity object: 与应用无关的(一般是持久性的)领域软件对象
- boundary object: 接口的抽象
- control object:控制器模式描述的用例处理者
- 优点
- 增加了可复用和接口可拔插的潜力
- 获得了推测用例状态的机会
- 臃肿的控制器
- 迹象
- 只有一个控制器类来接收系统中全部的系统事件,而且有很多系统事件
- 为了处理系统时间,由控制器完成诸多必要的任务,而不是把工作委派出去
- 控制器有很多属性并且他维护关于系统或领域的重要信息,(这些职责本应分配给其他对象)或者他要复制在其他地方才能找到的信息
- 解决方案
- 增加控制器
- 设计控制器,是他吧完成每个系统操作的职责委派给其他对象
- High Cohesion:怎样使对象保持有内聚、可理解和可管理,同时具有支持低耦合的附加作用
- 低内聚意味着对象仅靠本身工作,并且需要和大量其他对象进行协作,所有交互也都趋向高耦合
- 优点
- 能够更加轻松、清楚地理解设计
- 简化维护和改进工作
- 通常支持低耦合
- 由于内聚的类可以用于某个特定目的,因此细粒度、相关性强的功能的重要性增强