[OOD] 为什么单一职责原则(SRP)是最难运用的

简介: 单一职责原则(SRP)已经几乎是每一个程序员都知道的设计原则。最早由Robert C. Martin在中正式提出。书中作者在结论中提到:  SRP是所有设计原则最简单的,但也是最难运用的。
单一职责原则(SRP)已经几乎是每一个程序员都知道的设计原则。最早由Robert C. Martin在<<敏捷软件开发 — 原则、模式与实践>>中正式提出。书中作者在结论中提到:
  SRP是所有设计原则最简单的,但也是最难运用的。(中文翻译有之一,略去了)

现实工作中,关于一个类是否符合SRP,或者是否有必要符合SRP的讨论是经常发生的。争论的关键在于职责的定义,但我理解SRP真正的核心是关注于变化。这并不是我的新见解,全是来自Martin大叔的解释:
  1. 首先职责的定义是: 引起变化的原因,不是由分类所决定的。如果存在相对的变化,才要考虑分离。
  2. 其次,关于引起变化的因素,不要空想。一定确信有变化的可能,才会加以考虑。

他的提醒是非常中肯的。实践中正是常常基于功能的分类来定义职责的。


举个例子。假如我们要开发一个学校的教职员工管理系统。需要定义一个教师员工的类(炒菜的师傅先就不考虑了),考虑到老师和班主任两个角色,通常会认为他有两类职责:
  . 教师 (班主任很可能会带课)
  . 班级的管理 (组织班委,整治一下早恋之类的)


这时你拿着设计到了一个寄宿学校,校长可能会告诉你,他们这里的教师会轮流值班,兼做保育员,照看住校的学生。又是一个新的职责,怎么办?

如果遵守单一职责的原则,我们应该增加一个接口:


果真要如此吗? 注意,如果是在一般的学校,保育员不是老师的本职工作,可在这所寄宿学校里,却是教师的本职工作,是和老师一起变化的。校长的反馈是: 

 “我们学校的教师必须担任保育工作,我并不认为这会是什么新职责。作为教师,要么接受,要么离开。至于班主任工作,确实还是其特殊的地方,不然也不会给担任班主任的老师多一点津贴了。”。


请再体会一下,关于保育员职责的讨论。如果两个职责/角色不是同时变化的,才考虑分离。如果确定同时变化,就没有必要分离。除非有一天,某个劳动部门到该寄宿学校检查,认为他们这样不符合某个法律规定,强制规定老师可以选择是否担当保育员。如此一来,两个职责就又变成独立变化的了,就可以考虑分离职责。

再进一步,如果是针对一个只有一个支教教师的小学,极为偏僻。这里的校长会告诉你:

   ”这个学校里的每一个教师,唯一的一个,既是校长,也是老师。我不认为还需要明确班主任做什么,教师做什么,在这里,只要学生需要的都要做。并且这里很穷,五年内都不见得再有新老师来。”。


这个感人的故事告诉我们,在这所学校里, 他不在了,这所学校也就不在了,完全没有什么相对的变化,也没有什么可以确认的变化。所以在这里的管理系统里,教职员工只有一个单实例类,:

(向朱敏才孙丽娜夫妇致敬!)

聊到这里,不知道我说清楚了没有!设计要跟着需求走,不能生硬的套理论。欢迎拍砖!

目录
相关文章
|
设计模式 Java
Java设计模式七大原则-单一职责原则
Java设计模式七大原则-单一职责原则
90 0
|
设计模式 算法
原则的重要性(单一职责原则-开放封闭原则)一
原则的重要性(单一职责原则-开放封闭原则)一
95 0
|
程序员 测试技术
面向对象设计五个基本原则
只有聪明人才能看见的简介~( ̄▽ ̄~)~
104 0
|
关系型数据库
面向对象的设计(OOD)原则了解一下
面向对象的设计(OOD)原则了解一下
216 0
|
设计模式
设计模式 - 六大设计原则之LoD(迪米特法则原则)
迪米特法(Law Of Demeter , LoD)则又叫最少知道原则(Least Knowledge Principle),最早是在1987年由美国Northeastern University的Ian Holland提出。 通俗的来讲,就是一个类对自己依赖的类知道的越少越好。也就是说,对于被依赖的类来说,无论逻辑多么复杂,都尽量地的将逻辑封装在类的内部,对外除了提供的public方法,不对外泄漏任何信息。
197 0
设计模式 - 六大设计原则之LoD(迪米特法则原则)
软件架构设计原则--迪米特原则
本专栏内容参考自:咕泡学院Tom老师的《Spring5核心原理与30个类手写实战》,仅作个人学习记录使用,如有侵权,联系速删
软件架构设计原则--迪米特原则
|
设计模式
迪米特原则|设计原则
本文是讲述 六大设计原则 的最后一篇,为大家讲述 迪米特原则
|
设计模式
设计模式七大原则——迪米特原则
设计模式七大原则——迪米特原则
设计模式七大原则——迪米特原则
|
设计模式
设计模式(十二)迪米特原则(最少知识原则)
迪米特(最少知识)法则:如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果其中一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用。
155 0
设计模式(十二)迪米特原则(最少知识原则)
|
设计模式
设计模式—— 五:迪米特原则
设计模式—— 五:迪米特原则
147 0
设计模式—— 五:迪米特原则