面向对象分析与设计Python版 创建者与信息专家模式


前言

通用职责分配软件模式 GRASP(General Responsibility Assignment Software Principles)是一组用于在面向对象设计中分配职责的模式。它提供了一系列关于如何在对象之间分配职责的建议,以实现高内聚和低耦合的设计。GRASP模式包括:

  • 信息专家(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类的实例。

class OrderItem:
    def __init__(self, product, quantity, price):
        self.product = product
        self.quantity = quantity
        self.price = price

    def get_total_price(self):
        return self.quantity * self.price


class Order:
    def __init__(self, customer):
        self.customer = customer
        self.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 = 0
        for i in self.items:
            total_price += i.get_total_price()
        return total_price


order = 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类将负责管理总体成绩相关的操作

class Student:
    """Student类是关于学生成绩的信息专家"""

    def __init__(self, stu_id, name):
        self.stu_id = stu_id
        self.name = name
        self.grades = {}

    def add_grade(self, course, grade):
        self.grades[course] = grade

    def 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] = student

    def get_student_grade(self, stu_id, course):
        """获取学生的课程成绩"""
        student = self.students.get(stu_id, None)
        if student:
            # 使用Student的信息专家来获取成绩
            return student.get_grade(course)
        else:
            return None

    def get_course_average(self, course):
        """获取所有学生指定课程的平均成绩"""
        stu_count = len(self.students)
        if stu_count == 0:
            return None
        total = 0
        for stu_id in self.students:
            grade = self.students[stu_id].get_grade(course)
            if grade:
                total += grade
        return 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版》专栏!关注不迷路~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值