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

embedded/2025/1/15 7:44:29/

文章目录


前言

通用职责分配软件原则 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版》专栏!关注不迷路~


http://www.ppmy.cn/embedded/154058.html

相关文章

【STM32-学习笔记-4-】PWM、输入捕获(PWMI)

文章目录 1、PWMPWM配置 2、输入捕获配置3、编码器 1、PWM PWM配置 配置时基单元配置输出比较单元配置输出PWM波的端口 #include "stm32f10x.h" // Device headervoid PWM_Init(void) { //**配置输出PWM波的端口**********************************…

FFmpeg硬件解码

使用FFmpeg进行硬件解码时,通常需要结合FFmpeg的API和硬件加速API(如CUDA、VAAPI、DXVA2等)。以下是一个简单的C代码示例,展示如何使用FFmpeg进行硬件解码。这个示例使用了CUDA作为硬件加速的后端。 1. 安装FFmpeg和CUDA 确保你…

Python脚本自动发送电子邮件

要编写一个Python脚本来自动发送电子邮件,你可以使用smtplib库来处理SMTP协议,以及email库来构建邮件内容。 安装必要的库 通常情况下,smtplib和email库是Python标准库的一部分,因此不需要额外安装。如果你使用的是较旧的Python版…

【make】makefile 函数全解

目录 makefile简介函数全解介绍相关链接字符串处理函数subst 函数—字符串替换patsubst 函数 — 模式字符串替换strip 函数 — 去空格findstring 函数 — 查找字符串filter 函数 — 过滤器filter-out 函数 — 过滤器sort 函数 — 排序word 函数 — 取单词wordlist函数 — 取一串…

《解锁鸿蒙Next系统人工智能语音助手开发的关键步骤》

在当今数字化时代,鸿蒙Next系统与人工智能的融合为开发者带来了前所未有的机遇,开发一款人工智能语音助手应用更是备受关注。以下是在鸿蒙Next系统上开发人工智能语音助手应用的关键步骤: 环境搭建与权限申请 安装开发工具:首先需…

Java线程详解

一、线程的基本概念 1. 什么是线程? 线程是程序执行的一个单元,它是进程中的一个实体,是被系统独立调度和分派的基本单位。一个进程可以包含多个线程,这些线程共享进程的资源,如内存空间和文件句柄,但每个…

【2025最新】机器学习类计算机毕设选题80套,适合大数据,人工智能

【2025最新】机器学习类型计算机毕设选题 1-10套 基于Spring Boot的物流管理系统的设计与实现 基于机器学习的虚假招聘信息的分析与预测 基于机器学习的影响数据科学家职业变动因素的分析与预测 基于Spring Boot的历史文物交流平台的设计与实现 基于机器学习的肥胖影响因素的分…

c++ 中的容器 vector、deque 和 list 的区别

表格汇总: 容器存储结构随机访问性能中间插入/删除性能两端插入/删除性能内存管理特点迭代器类型适用场景vector连续存储的动态数组 O ( 1 ) O(1) O(1) O ( n ) O(n) O(n)(需要移动元素)末尾: O ( 1 ) O(1) O(1),头部…