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).