前言
通用职责分配软件模式 GRASP(General Responsibility Assignment Software Principles)是一组用于在面向对象设计中分配职责的模式。它提供了一系列关于如何在对象之间分配职责的建议,以实现高内聚和低耦合的设计。GRASP模式包括:
- 信息专家(Information Expert):将职责分配给拥有完成该职责所需信息的类。
- 创建者(Creator):将创建对象的职责分配给与该对象存在某种关系的类。
- 控制器(Controller):将处理系统事件的职责分配给表示用例场景的类或表示系统中协调者的类。
- 低耦合(Low Coupling):尽量减少类与类之间的依赖关系。
- 高内聚(High Cohesion):尽量将相关的职责分配给同一个类。
- 多态(Polymorphism):通过接口或抽象基类来定义通用行为,让子类实现具体行为。
- 纯虚构(Pure Fabrication):创建一些没有直接映射到问题域的类,以更好地实现低耦合和高内聚。
- 间接性(Indirection):通过引入间接层来降低类之间的直接依赖。
- 隔离变化(Protected Variation):设计系统时,尽量减少对变化的部分的依赖。
一、低耦合模式
低耦合模式
- 名称:低耦合(Low Coupling)
- 应用场景:耦合度是指模块间相互依赖的程度,低耦合意味着模块间的相互依赖性较低,一个模块的变化对其他模块的影响较小。
- 解决方案:
- 使用接口:通过定义接口来抽象化实现细节,这样其他模块只需与接口交互,而不必关心具体实现。
- 最小化共享信息:尽量减少模块间的共享数据,共享数据越多,耦合度越高。
- 依赖注入:通过依赖注入来提供模块所需的依赖项,而不是在模块内部创建依赖项,这样可以减少模块间的直接依赖。
- 使用事件和消息传递:模块之间通过事件或消息传递进行通信,而不是直接的方法调用,这样可以降低它们之间的耦合。
- 分层和分层架构:通过将系统划分为多个层次,每个层次只与相邻的层次交互,可以减少跨层次耦合。
- 适度使用继承:在继承关系中,子类与父类的耦合非常紧密。建议能用组合的地方不要用继承。
- 优点:有助于提高软件系统的可维护性和可扩展性,增加可重用性
低耦合模式补充说明
-
低耦合与高内聚:
- 低耦合是指不同模块之间的依赖关系尽可能少。模块之间通过定义良好的接口进行通信,而不是直接依赖于其他模块的实现细节。
- 高内聚是指模块内部各个元素之间紧密相关,共同完成一个单一的功能或任务。内聚性高的模块通常只包含完成一个任务所需的元素。
-
低耦合是一种评估模式,是对设计方案进行评价的一种指标
-
低耦合是整个设计阶段都要考虑的模式
-
低耦合与其他的模式,如信息专家、高内聚必须综合考虑
-
X与Y存在耦合情况:
- X有一个指向Y的属性
- X调用Y提供服务
- X有一个引用Y(参数、局部变量或返回值)的方法
- X是Y的直接或间接子类
- Y是一个接口,X实现该接口
-
类之间存在适度的耦合是正常的、必须的。
示例
一个简单的日志记录系统,包含两个组件:Logger 和 FileWriter。设计一种低耦合方案:
Logger
不直接处理文件写入逻辑,而是通过FileWriter
的接口来写入日志。- 如果想要改变日志的写入方式(例如,写入到数据库或网络服务),只需要创建一个新的写入器类,并遵循
FileWriter
的接口,而不需要修改Logger
类。
class Logger:
def __init__(self, writer):
self.writer = writer
def log(self, msg):
self.writer.write(msg)
class FileWriter:
def __init__(self, file_name):
self.file_name = file_name
def write(self, msg):
with open(self.file_name, "a", encoding="utf-8") as f:
f.write(msg + "\n")
file_writer = FileWriter("app.log")
logger = Logger(file_writer)
logger.log("GET /index.html HTTP/1.1")
logger.log("POST /login.php HTTP/1.1")
### 文件app.log结果
GET /index.html HTTP/1.1
POST /login.php HTTP/1.1
二、高内聚模式
高内聚模式
- 名称:高内聚 high cohesion
- 应用场景:高内聚指的是一个模块或类内部的元素(如方法、属性)之间相互关联的程度很高,且这些元素共同工作以实现一个单一、清晰的责任或功能。
- 解决方案:
- 确保类的属性和方法紧密相关:一个类中的所有属性和方法都应该服务于同一个目的或职责。
- 避免上帝类:不要创建承担过多职责的类,这样的类通常被称为“上帝类”。
- 模块化:将功能划分为小的、内聚的模块,每个模块负责一个具体的功能。
- 重构:在开发过程中不断重构代码,以提高内聚性。
- 优点:有助于提高系统的可维护性、可理解性和可重用性
高内聚模式补充说明
-
高内聚是一种评估模式,是对设计方案进行评价的一种指标
-
高内聚是整个设计阶段都要考虑的模式
-
高内聚必须和信息专家、低耦合等其他模式综合考虑
-
高内聚模块或类的特点
- 有较少数量的操作,操作的性质基本一致,不会做太多的事情
- 如果同类别的工作太多,则会定义新的类分担任务,相互间合作
-
低内聚模块或类的特点
- 大粒度的抽象
- 做了太多本应该委托给其他类去做的工作
示例
下面两个设计方案,从高内聚角度考虑,方案二更优。
方案一:控制器类Register负责创建支付对象Payment,然后交给销售Sale。这样下去,控制器类Register将越来越多地承担任务并变得不内聚。
方案二:控制器类Register将创建支付对象Payment的责任,委托给销售Sale。
您正在阅读的是《面向对象分析与设计Python版》专栏!关注不迷路~