GRASP:更多具有职责的对象
目标:
- 学习使用其余的GRASP模式。
一旦理解了GRASP模式,我们就拥有了讨论设计的丰富、共享额词汇。随着对GoF设计模式的介绍,我们的设计词汇将不断丰富起来。
多态
问题
如何处理基于类型的选择?如何创建可拔插的软件构件?
- 基于类型的选择:条件变化时程序的一个基本主题。如果使用if-then-else或case语句的条件逻辑来设计程序,那么当出现新的变化时,则需要修改这些case逻辑-通常遍布各处。这种方法很难方便地扩展有新变化的程序,因为可能需要修改程序的多个地方-任何存在条件逻辑的地方。
- 可拔插软件构件:客户-服务器关系中的可视化构件,如何才能够替换服务器构件,而不对客户端产生影响呢?
解决方案
当相关选择或行为随类型有所不同时,使用多态操作为变化的行为类型分配职责。
推论:不要测试对象的类型,也不要使用条件逻辑来执行基于类型的不同选择。
讨论
多态是一个基本的设计原则,用于设计系统如何组织以处理类似的变化。基于多态分配职责的设计能够被简便爹扩展以处理新的变化。
准则:何时使用接口进行设计
多态意味着在大部分OO语言中要使用抽象超类或接口。何时应该考虑使用接口?普遍的答案是,当你想要支持多态但是又不想约束于特定的类层次结构时,可以使用接口。
禁忌
有时,开发者会针对某些未知的可能性变化进行“未来验证”的推测,由此而使用接口和多态来设计系统。如果这种变化点时基于立即或十分可能变化的原因而明确存在的,那么通过多态来增加灵活性一定时合理的。但是,这里需要有临界评价,因为有些时候使用多态设计形成的变化点在实际中不一定发生或从未实际发生过,这种不惜要的付出很常见。在投入灵活性的该金钱,要现实地对待可变性的真是可能性。
优点
- 易于增加新变化所需的扩展。
- 无需影响客户便甭管引入新的实现。
相关模式
- 防止变异
- 大量流行的GOF设计模式。
别称和类似模式
选择消息,不要询问“什么类型”。
纯虚构
问题
当你并不像违背高内聚和低耦合或其他目标,但是基专家模式所提供的方案又不合适时,哪些对象应该承担这一职责?
面向对象设计有时会被描述为:实现软件类,使其表示真实世界问题领域的概念,以降低表示差异。然而,在很多情况下,只对领域层对象分配职责会熬制不良内聚或耦合,或者会降低复用潜力。
解决方案
对人为指导的类分配一组高内聚的职责,该类并不代表问题领域的概念--虚构的事物,用以支持高内聚、低耦合和复用。
这种类时凭空虚构的。理想状况下,分配给这种虚构物的职责要支持高内聚和低耦合,使这种虚构物清晰或纯粹--因此称为纯虚构。
讨论
此类对象的设计可以被广泛地分为两组:
- 通过表示解析所产生的选择。
- 通过行为解析所产生的选择。
表示解析使对象设计中常见的策略,并支持低表示差异的目标。但是有时,我们需要通过对行为分组或通过算法来分配职责,而无需创建任何名称或目的使现实世界领域概念相关的类。
识别类是否为纯虚构并不重要,这只是表示普遍思想的教学概念,即有些软件类源于领域中的表示,而有些软件类只是对象设计者为图方便而捏造的。设计这些编译了通常使为了组合异常常用行为,其动机正式行为解析而非表示解析。
换言之,纯虚构通常基于相关的功能性进行划分,因此这是一种以功能为中心的或行为的对象。
大量现有的面向对象设计模式都是村虚构的例子:适配器、策略、命令。
最后值得提及的是:有时根据信息专家模式所提供的方案并不是所需的。即使对象由于持有大量相关信息而被作为职责的候选者,但是在其他方面,这种选择会导致不良设计,通常是由于内聚和耦合种的问题。
优点
- 支持高内聚,因为职责被解析为细粒度的类,这种类只着重于极为特定的一组相关任务。
- 增加了潜在的复用性,因为细粒度纯虚构类的职责可适用于其他应用。
禁忌
那些对象设计初学者和更熟悉以功能组织和分解软件的人有时会滥用行为解析及纯虚构对象。夸张的是、功能正好变成了对象。创建“功能”或“算法”对象本来没有错,但是这需要平衡于表示解析设计的能力,这边便能够使注入Sale等表示类类同样具有职责。信息专家所支持的目标使,将职责于这些职责所需信息结合起来赋予同一个对象,以实现对低耦合的支持。如果滥用纯虚构,会导致大量行为对象,其职责于执行职责所需的信息没有结合其他,这样会对耦合产生不良影响。其通常征兆使,对象内的大部分数据被传递给其他对象用以处理。
相关模式和原则
- 低耦合
- 高内聚
- 纯虚构通常会接纳本来是依据转换模式所分配给领域类的职责。
- 所有GOF设计模型都是纯虚构。
- 事实上,所有其他设计模式也都是纯虚构的。
间接性
问题
为了避免两个或多个事物之间直接耦合,应该如何分配职责?如何是对象解耦,以支持低耦合并提高复用性潜力?
解决方案
将职责分配给中介对象,使其作为其他构件或服务之间的媒介,以避免它们之间的直接耦合。中介实现了其他构件之间的间接性。
讨论
计算机科学种的大多数问题都可以通过增加以层间接性来解决,这一个眼特别适用于i安心对象设计。
优点
- 实现了构件之间的低耦合。
相关模式和原则
- 防止变异
- 低耦合
- 大量GOF模式,诸如:适配器、桥接、外观、观察者和中介。
- 大量间接性中介都是纯虚构。
防止变异
问题
如何设计对象、子系统和系统,使其内部的变化或不稳定性不会对其他元素产生不良影响?
解决方案
识别预计变化或不稳定之处,分配职责用以在这些变化之外创建稳定接口。
讨论
这是非常重要和基本的软件设计原则!本书中几乎所有的软件或架构设计技巧都是防止变异的特例。
源于防止变异的机制
- 防止变异的核心机制:数据封装、接口、多态、间接性和标准。
- 数据驱动设计:
- 服务查询
- 解释器驱动的设计
- 反射或元级的设计
- 统一访问
- 标准语言
- Liskov替换原则
隐藏结构的设计
在方法里,直营给以下对象发送消息:
- this对象
- 方法的参与
- this的属性
- 作为this属性的集合种额元素
- 在方法种创建的对象
其意图是避免客户于简洁对象和对象之间的对象连接产生耦合。
禁忌
警告:预测PV和选择你的战投
首先,值得定义以下两个变更点:
- 变化点:现有、当前系统或需求种的变化
- 进化点:预测将来可能会产生的变化点,当并不存在现有需求种。
对鲜花店和进化点,都可以应用PV
警告:有时,对进化点进行“将来验证”预测放入成本要大于由真实变化迫使的对原有较为“脆弱”的简单设计进行重新设计的成本。
这里并不是提倡重新设计和脆弱的设计。如果实际需要灵活性和对变化的预防,那么就应该应用PV。但是如果预测将来验证或预测“复用”的坑行是否不确定,则需要由可知和批判的态度。
优点
- 易于增加新变化所需的扩展。
- 可以引入新额实现而无需影响客户。
- 低耦合
- 能够降低变化的成本影响。
相关模式和原则
- 大部分设计原则和模式都是防止变异的机制
- 变化点和进化点被称为“热点”