QZQ的小世界!

  • 首页
你好!
这里是QZQ的博客站!
  1. 首页
  2. 未分类
  3. 正文

单一职责原则——Python案例理解

2024年12月30日 285点热度 0人点赞 0条评论

定义

这个原则还是挺简单易懂的,就是一个类应该只负责具体的一项工作。那完成计时也是工作,完成AI模型训练也是工作,工作大小如何界定?

单一职责原则的原话是:

一个类应该有且只有一个变化的原因。

为什么将不同的职责分离到单独的类中是如此的重要呢?

因为每一个职责都是一个变化的中心。当需求变化时,这个变化将通过更改职责相关的类来体现。

如果一个类拥有多于一个的职责,则这些职责就耦合到在了一起,那么就会有多于一个原因来导致这个类的变化。对于某一职责的更改可能会损害类满足其他耦合职责的能力。这样职责的耦合会导致设计的脆弱,以至于当职责发生更改时产生无法预期的破坏。

案例理解

我们设计一个矩形类,这个矩形类有两个职能,一是计算面积,二是生成矩形图形并且绘制到窗口中。

class Rectangle:
    def __init__(self, width, height):
        # 一个简单的矩形类,拥有长和高
        self.width = width
        self.height = height

    def area(self):
        return self.width * self.height

    def draw(self):
        import cv2
        import numpy as np
        
        # 这里调用python-opencv库为我们绘制矩形,用法就不介绍了
        img = np.zeros((512, 512, 3), np.uint8)
        cv2.rectangle(img, (0, 0), (self.width, self.height), (0, 0, 255))
        cv2.imshow("image", img)
        cv2.waitKey(0)

 

emm,由于我们用的是python,所以其实很多之前的编程语言要考虑的问题,我们其实不需要太担心。

比如:

我们必须在计算几何应用中包含对 GUI 库的引用。这导致应用程序无谓的消耗了链接时间、编译时间、内存空间和存储空间等。

python是动态语言,所有的代码都经过翻译后交给解释器来直接运行。之前这项原则考虑的是:“如果有一个用户用不到绘制图形的函数,那么事先要求该用户准备有关图形显示的环境会引起资源的老费”。这在我们这个案例的函数中是这两行:

import cv2
import numpy as np

 

然而,由于python的特性,你如果并不使用draw函数,那么这两个库根本不会进行导入操作(因为我们把导入库的语句写到了函数里),且你的环境中没有这个包也不会报错!

当然,如果你将这两句导入语言写到文件头部那自然该报错还是会报错,而且这种写法更常见。

话题有点偏了,回来看看一般会造成什么样的问题:

  • 代码难以理解与维护:由于Rectangle类包含了多种不相关的职责,其他开发者在阅读或修改代码时可能会感到困惑,难以快速定位问题。
  • 高耦合度:不同的职责之间可能存在紧密的联系,一旦某个职责的实现发生变化,就可能影响到其他职责。(本例中,所有的函数都需要调用类的自身属性,即 self.width,self.height,扩写很可能会产生属性冲突之类的问题)
  • 难以复用:由于功能混杂,Rectangle类很难被其他系统或模块重用。
  • 扩展性差:当需要添加新的功能时,由于类的职责已经过多,可能不得不继续在这个类中增加方法,导致类变得更加庞大和复杂。

解决办法自然是将我们的Rectangle类分开,一个专注于数学运算成为“几何矩形”,另一个就专注实现图像显示即可。当然,由于“几何矩形”是非常精简的,可以考虑让“几何矩形”成为基类,代码就会成为下面这样:

class GeometricRectangle:
    def __init__(self, width, height):
        # 一个简单的矩形类,拥有长和高
        self.width = width
        self.height = height

    def area(self):
        return self.width * self.height


class GraphicRectangle(GeometricRectangle):
    def __init__(self, width, height):
        # 一个简单的矩形类,拥有长和高
        super().__init__(width, height)

    def draw(self):
        import cv2
        import numpy as np

        # 这里调用python-opencv库为我们绘制矩形,用法就不介绍了
        img = np.zeros((512, 512, 3), np.uint8)
        cv2.rectangle(img, (0, 0), (self.width, self.height), (0, 0, 255))
        cv2.imshow("image", img)
        cv2.waitKey(0)

 

这样耦合就解开了,如果我们之后有什么应用需要调用几何矩形,就可以尽管使用这个较为简洁的几何矩形类,而不用考虑额外的环境配置和类方法间的影响了。

参考

单一职责原则(Single Responsibility Principle) - sangmado - 博客园

为什么强调单一职责,为什么那么多人都习惯违反这一职责? - 知乎

面向对象编程的六大原则

最少知识原则——Python案例理解 - QZQ的小世界!

开放封闭原则——Python案例理解 - QZQ的小世界!

里氏替换原则——Python案例理解 - QZQ的小世界!

依赖倒置原则——Python案例理解 - QZQ的小世界!

单一职责原则——Python案例理解 - QZQ的小世界!

接口分离原则——Python案例理解 - QZQ的小世界!

本作品采用 知识共享署名-非商业性使用 4.0 国际许可协议 进行许可
标签: 暂无
最后更新:2025年3月12日

QZQ

一只涉猎广泛的技术爱好者,绝赞养猫中~

点赞
< 上一篇
下一篇 >

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复

归档

  • 2025 年 4 月
  • 2025 年 3 月
  • 2025 年 2 月
  • 2025 年 1 月
  • 2024 年 12 月
  • 2024 年 11 月

分类

  • 技术
  • 未分类

COPYRIGHT © 2024 QZQ的小世界!. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang