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)是设法让物件适当的聚焦、可管理以及可理解的评估模式。高内聚性常常会用来支持低耦合性。高内聚性是指特定组件的多个职责是彼此紧密有关,高度聚焦的。将程序分解为类别和子系统是增加系统内聚性的一种方式。相对的,低内聚性是指特定组件有太多不相关的职责。低内聚性的组件常会难以理解、复用、维护及改变[3]:314–315。
多态
编辑依照多态(polymorphism)的原则,依类型变更行为的职责是在出现变更的类型上。这可以用多态运算符实现。这类类型的用户需要用多态运算符。
问题: 如何处理依类型的变化?如何产生可可插拔的软件组件?
解决方案:当一些行为会因为类型(类别)而变化,用多态运算符将此职责分派到类型出现变化的类型。(多态有许多的定义,在此处的定义是“在不同物件上的服务给予相同的名字”)
保护变化
编辑保护变化(protected variations)模式保护组件,不受其他组件(物件、系统、子系统)变化的影响,作法是将聚焦在不稳定部分的程序包裹在接口内,利用多态来产生此一接口的不同实现。
问题: 如何设计物件、子系统和系统,让组件的变化或不稳定性不会对其他组件有不好的影响?
解决方案:识别预期到的变异或不稳定性,指定职责在其周围产生稳定的接口。
纯虚构
编辑纯虚构(pure fabrication)是指没有实现问题领域概念的类别,特别是为了实现派生类低耦合性、高内聚性、高复用的潜力(若是用资讯专家的解决方案,无法达到此一效果)。这类类别在领域驱动设计中会称为服务。
相关模式或原则:
- 低耦合性
- 高内聚性
相关条目
编辑参考资料
编辑- ^ Craig Larman. Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and the Unified Process (PDF) 2nd. Prentice Hall. 2001 [2021-04-22]. ISBN 0-13-092569-1. (原始内容 (PDF)存档于2021-04-22).
- ^ Muhammad Umair. SOLID, GRASP, and Other Basic Principles of Object-Oriented Design. DZone. 2018-02-26 [2021-04-22]. (原始内容存档于2021-04-22).
- ^ 3.0 3.1 3.2 3.3 Craig Larman. Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and Iterative Development 3rd. Pearson. 2004. ISBN 978-0131489066.
- ^ Application Layer like business facade?. Yahoo! Groups (domaindrivendesign). [2010-07-15]. (原始内容存档于2020-08-07).