面向对象设计的九大基本原则 (GRASP)

Posted JavaEdge.

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面向对象设计的九大基本原则 (GRASP)相关的知识,希望对你有一定的参考价值。

GRASP是通用职责分配软件模式(General Responsibility Assignment Software Patterns)的简称,是面向对象设计和职责分配中的九个基本原则[1]:6,最早是在克雷·拉蒙1997年的Applying UML and Patterns书中提到。

GRASP中提到的模式和原则包括有控制器(controller)、创建者(creator)、中介(indirection)、信息专家(information expert)、低耦合性(low coupling)、高内聚性(high cohesion)、多态(polymorphism)、保护变化(protected variations)和纯虚构(pure Fabrication)[2]。这些模式都是针对软件开发上的一些问题进行解决。发明这些技巧不是为了要创造新的工作方式,而是为在面向对象设计上,旧的,经过测试的程序设计方式创建文档并且标准化。

克雷·拉蒙提到:“软件开发最关键的设计工具不是UML或其他的技术,是明了设计原则的心智。”[3]:272。因此,GRASP原则是心理层面的工具集,在面向对象软件设计学习上的辅助工具。

模式

在面向对象设计中,设计模式是针对问题以及其解决方案一个有命名的描述方式,可以应用在不同的情境中。理想的设计模式可以让程序开发者知道要如何将解决方案应用在不同的环境下,并且进行取舍。在一些特定类型的问题中,许多模式会提供对象职责分配的指南。

信息专家

问题: 分配职责给对象的基本原则是什么?
解决方案:找到实现职责需要有的信息,将职责分配给有此信息的对象

信息专家(Information expert)是决定如何分配职责(给方法、字段等)的原则。

应用信息专家的原则,常见指定职责的作法是针对特定的职责,确认要实现此职责要有什么信息,以及信息存在的对象。

这会将职责分配到有最多和职责有关信息的对象[3]:17:11

相关模式或原则:低耦合性、高内聚性

创建者

参见:工厂方法
对象的创建是面向对象系统中常见的活动之一。因此需要确认哪一个类别有职责创建对象。

问题:哪个类别要创建对象A?
解决方案:一般而言,类别B若符合以下一个(也有可能是多个)条件,有权责要创建对象A:

B的实例包括A的实例,或是合成聚合A的实例
B的实例会纪录A的实例
B的实例密切的使用A的实例
B的实例有A的实例初始化时的信息,在创建对象时会传递给A的实例[3]:16:16.7
相关模式或原则:低耦合性、工厂方法

控制器

控制器(controller)模式会将处理系统对象的职责指定给表现整个系统或是用例场景的非用户界面类别。控制器对象是非用户界面,负责接收或处理系统事件的对象。

问题:哪个对象要处理输入系统事件?
解决方案:应该由用例控制器来处理用例所有的系统事件,也可以用在一个以上的用例。例如“创建用户”或“删除用户”的用例,可以用同一个类别,称为UserController,而不是用二个个别的用例控制器。

控制器定义为在用户界面之后,接收及处理系统动作的第一个对象。控制器需将需其他对象来完成的工作给对应对象。控制器协调或是控制相关活动。在信息系统逻辑架构的面向对象系统中,若应用程序在应用层/服务层和业务逻辑之间有明确的分隔,GRASP控制器可以视为是应用层或是服务层的一部分[4]。

相关模式或原则:命令模式、外观模式、层、纯虚构

中介

中介(indirection)模式支持低耦合性,在二个对象之间将其职责指定到中介的对象,因此可以复用。其中一个例子是在模型—视图控制模式中,在资料(模型)和其实现(视图)之间导入控制器组件。这可以确保二个组件之间的低耦合性。

问题: 在二个或多个对象之间,要如何分配职责才能避免耦合?如何将对象解耦,才能支持低耦合度,且维持较高的复用潜力?
解决方案:将职责分配给二个或多个组件之间的中介对象或服务,让组件之间不会直接耦合

低耦合性

主条目:松耦合
耦合性是评估一组件链接另一组件,知道另一组件,或是依赖另一组件的程度。松耦合是为了以下的优点,指派职责的评估模式:

类别之间的相依性低
一个类别的修改对另一个类别的影响较小
复用潜力较高

高内聚性(high cohesion)

是设法让对象适当的具焦、可管理以及可理解的评估模式。高内聚性常常会用来支持低耦合性。高内聚性是指特定组件的多个职责是彼此紧密有关,高度具焦的。将程序分解为类别和子系统是增加系统内聚性的一种方式。相对的,低内聚性是指特定组件有太多不相关的职责。低内聚性的组件常会难以理解、复用、维护及改变。

多态

主条目:多态 (计算机科学)
依照多态(polymorphism)的原则,依类型变更行为的职责是在出现变更的类型上。这可以用多态运算符实现。这类类型的用户需要用多态运算符。

问题: 如何处理依类型的变化?如何产生可可插拔的软件组件?
解决方案:当一些行为会因为类型(类别)而变化,用多态运算符将此职责分派到类型出现变化的类型。(多态有许多的定义,在此处的定义是“在不同对象上的服务给予相同的名字”)

保护变化

参见:开闭原则
保护变化(protected variations)模式保护组件,不受其他组件(对象、系统、子系统)变化的影响,作法是将具焦在不稳定部分的程序包裹在接口内,利用多态来产生此一接口的不同实现。

问题: 如何设计对象、子系统和系统,让组件的变化或不稳定性不会对其他组件有不好的影响?
解决方案:识别预期到的变异或不稳定性,指定职责在其周围产生稳定的接口。

纯虚构

纯虚构(pure fabrication)是指没有实现问题领域概念的类别,特别是为了实现派生类低耦合性、高内聚性、高复用的潜力(若是用信息专家的解决方案,无法达到此一效果)。这类类别在领域驱动设计中会称为服务。

相关模式或原则:

低耦合性
高内聚性

以上是关于面向对象设计的九大基本原则 (GRASP)的主要内容,如果未能解决你的问题,请参考以下文章

面向对象设计原则 面向对象设计原则都有哪些

面向对象设计的三个原则

面向对象设计的6个设计原则最早谁提出的

面向对象设计的基本原则都有哪些

设计模式2 面向对象设计原则

面向对象七大设计原则