前言
通用职责分配软件原则 GRASP(General Responsibility Assignment Software Principles),是一组用于指导软件设计,尤其是在面向对象设计中的原则。包括以下九个主要原则:
- 信息专家(Information Expert):将职责分配给拥有完成该职责所需信息的类。
- 创建者(Creator):将创建对象的职责分配给与该对象存在某种关系的类。
- 控制器(Controller):将处理系统事件的职责分配给表示用例场景的类或表示系统中协调者的类。
- 低耦合(Low Coupling):尽量减少类与类之间的依赖关系。
- 高内聚(High Cohesion):尽量将相关的职责分配给同一个类。
- 多态(Polymorphism):通过接口或抽象基类来定义通用行为,让子类实现具体行为。
- 纯虚构(Pure Fabrication):创建一些没有直接映射到问题域的类,以更好地实现低耦合和高内聚。
- 间接性(Indirection):通过引入间接层来降低类之间的直接依赖。
- 防止变异(Protected Variation):设计系统时,尽量减少对变化的部分的依赖。
一、创建者原则
-
名称:创建者(Creator)。
-
应用场景:确定谁负责创建目标类型对象。
-
解决方案:5个对象创建行为的职责分配原则。
-
类B对象是类A对象的聚合体,则B创建A的实例。
-
类B对象包含类A对象,则B创建A的实例。
-
类B对象保存A对象,则B创建A的实例。
-
类B对象使用A对象,则B创建A的实例。
-
类B对象持有A对象初始化所需的数据,则B创建A的实例。
-
-
使用前提:保证业务逻辑一致或正确。
-
优点:降低代码耦合。
-
缺陷:有可能会导致对象创建行为分散或不一致。
示例
一个订单处理系统,其中包含两个类:Order(订单)和OrderItem(订单项)。根据Creator原则,Order类应该负责创建OrderItem类的实例。
python">class OrderItem:def __init__(self, product, quantity, price):self.product = productself.quantity = quantityself.price = pricedef get_total_price(self):return self.quantity * self.priceclass Order:def __init__(self, customer):self.customer = customerself.items: list[OrderItem] = []def add_item(self, product, quantity, price):# Order类应该负责创建OrderItem类的实例item = OrderItem(product, quantity, price)self.items.append(item)def get_total_order_price(self):total_price = 0for i in self.items:total_price += i.get_total_price()return total_priceorder = Order("张三")
order.add_item("面包", 3, 2.9)
order.add_item("笔", 2, 1.9)
print(f"总价:{order.get_total_order_price():.2f}")### 输出结果
总价:12.50
二、信息专家原则
- 名称:信息专家(Information Expert)
- 应用场景:确定目标行为职责应该分配给哪个类或对象。
- 解决方案:
- 具有行为实现所需业务信息(或数据)的类称为信息专家。
- 目标行为职责分配给信息专家类或对象,即将职责分配给拥有执行该职责所需信息的类。
- 优点:降低代码耦合,保持专家类的封装特性。
- 缺陷:有可能生成浮肿类。
示例
一个学校管理系统,其中包括两个类:Student(学生)和Gradebook(成绩册)。根据信息专家原则,Student类将负责管理关于单个学生的信息,而Gradebook类将负责管理总体成绩相关的操作。
python">class Student:"""Student类是关于学生成绩的信息专家"""def __init__(self, stu_id, name):self.stu_id = stu_idself.name = nameself.grades = {}def add_grade(self, course, grade):self.grades[course] = gradedef get_grade(self, course):return self.grades.get(course, None)class Gradebook:"""Gradebook类是关于所有学生平均/加总成绩的信息专家"""def __init__(self):self.students: dict[int, Student] = {}def add_student(self, student: Student):self.students[student.stu_id] = studentdef get_student_grade(self, stu_id, course):"""获取学生的课程成绩"""student = self.students.get(stu_id, None)if student:# 使用Student的信息专家来获取成绩return student.get_grade(course)else:return Nonedef get_course_average(self, course):"""获取所有学生指定课程的平均成绩"""stu_count = len(self.students)if stu_count == 0:return Nonetotal = 0for stu_id in self.students:grade = self.students[stu_id].get_grade(course)if grade:total += gradereturn round(total / stu_count, 2)stu1 = Student(1, "张三")
stu2 = Student(2, "李四")
stu1.add_grade("语文", 80)
stu1.add_grade("数学", 90)
stu2.add_grade("语文", 85)
stu2.add_grade("数学", 95)gradebook = Gradebook()
gradebook.add_student(stu1)
gradebook.add_student(stu2)print(f"张三语文成绩:{gradebook.get_student_grade(1,'语文')}")
print(f"班级数学平均成绩:{gradebook.get_course_average('数学')}")###输出结果
张三语文成绩:80
班级数学平均成绩:92.5
您正在阅读的是《面向对象分析与设计Python版》专栏!关注不迷路~