【设计模式七大原则】单一职责原则
单一职责原则(Single Responsibility Principle)
定义
每个类都应该实现单一的职责,即有且只有一个原因引起类的变更。
图例
分析
实际生活中我们已经有意无意在使用这一原则了,因为它是符合我们人思考问题的方式的。比如我们在整理衣柜的时候,为了方便拿衣服我们会把夏天的衣服放在一个柜子中,冬天的衣服放在一个柜子。这样季节变化的时候,我们只要到对应的柜子直接拿衣服就可以了。否则如果冬天和夏天的衣服都放在一个柜子中,我们找衣服的时候可就费劲了。放到软件代码设计中,我们也需要采用这样的分类思维。在进行类设计的时候,要设计粒度小、功能单一的类,而不是大而全的类。
类的职责主要包括两个方面:数据职责和行为职责,数据职责通过其属性来体现,而行为职责通过其方法来体现。一个类(或者大到模块,小到方法)承担的职责越多,它被复用的可能性越小,而且如果一个类承担的职责过多,就相当于将这些职责耦合在一起,当其中一个职责变化时,可能会影响其他职责的运作。
单一职责原则是实现高内聚、低耦合的指导方针,在很多代码重构手法中都能找到它的存在,它是最简单但又最难运用的原则,需要设计人员发现类的不同职责并将其分离,而发现类的多重职责需要设计人员具有较强的分析设计能力和相关重构经验。
意义
一个类不能做太多的东西。在软件系统中,一个类(一个模块、或者一个方法)承担的职责越多,那么其被复用的可能性就会越低。一个很典型的例子就是万能类。其实可以说一句大实话:任何一个常规的MVC项目,在极端的情况下,可以用一个类(甚至一个方法)完成所有的功能。但是这样做就会严重耦合,甚至牵一发动全身。如果一个类承担的职责过多,就等于把这些职责耦合在一起了。一个职责的变化可能会削弱或者抑制这个类完成其他职责的能力。这种耦合会导致脆弱的设计,当发生变化时,设计会遭受到意想不到的破坏。而如果想要避免这种现象的发生,就要尽可能的遵守单一职责原则。将这些职责进行分离,将不同的职责封装在不同的类中,即将不同的变化原因封装在不同的类中,如果多个职责总是同时发生改变则可将它们封装在同一类中。此原则的核心就是解耦和增强内聚性。
代码实例
比如我们刚开始编程学习的学生管理系统,我们把学生和课程定义到了一个类,既有学生信息的操作比如创建或者删除动作,又有关于课程的创建以及修改动作
class Student:
def __init__(self):
pass
# 设置学生姓名
def updateName(self, name):
pass
# 设置学生年级
def updateGrade(self, num):
pass
# 增加课程
def AddCourses(self):
pass
# 删除课程
def DelCourses(self):
pass
那么我们可以认为这个类时不满足单一职责的设计原则的,因为它将两个不同业务域的业务混杂在了一起,所以我们需要进行拆分,将这个大而全的类拆分为学生以及课程两个业务域,这样粒度更细,更加内聚。
class Student:
def __init__(self):
pass
# 设置学生姓名
def updateName(self, name):
pass
# 设置学生年级
def updateGrade(self, num):
pass
class Courses:
# 增加课程
def AddCourses(self):
pass
# 删除课程
def DelCourses(self):
pass
优点
单一职责原则是实现高内聚低耦合的最好方法,没有之一。
类的复杂性降低,可读性提高,维护性提高。变更引起的风险降低
降低类的复杂性,类的职责清晰明确。比如数据职责和行为职责清晰明确。 2、提高类的可读性和维护性, 4、变更引起的风险减低,变更是必不可少的,如果接口的单一职责做得好,一个接口修改只对相应的类有影响,对其他接口无影响,这对系统的扩展性、维护性都有非常大的帮助。
缺点
造成代码量的增加,类多了,使用成本(理解成本)也高了
注意事项
通常情况下,我们应当遵守单一职责原则,只有逻辑足够简单,才可以在代码级违反单一职责原则:只有类种方法数量足够少,可以在方法级别保持单一职责原则。
适用场景
方法级别的单一职责原则:一个方法只负责一件事
类级别的单一职责原则:一个类只负责一件事
类库级别的单一职责原则:一个类库职责要清晰
项目级别的单一职责:一个项目应该职责要清晰(客户端/管理后台/后台服务/定时任务/分布式引擎)
系统级别的单一职责:为通用功能拆分系统(IP定位/日志/在线统计)
- 点赞
- 收藏
- 关注作者
评论(0)