初学者在编程的时候可能一开始会有这样的经历,使用一个类来实现很多的功能,新添加的甚至不相关的功能都放在一个类里来实现,煮成了一锅大杂烩,往往使得某个类包罗万象,无所不能。可能刚开始实现功能比较简单,这样做不会引发什么特别大的问题。但是随着项目复杂度的提升,各种不相关的实现代码耦合在一起,一旦有功能的更改或增删,修改的代码很可能会导致其他功能的正常运行。这种编程方式显然是不可取的,也就是违背了所谓的单一职责原则。
原文链接:http://tianweili.github.io/blog/2015/02/25/single-responsibility-principle/
什么是单一职责原则?
单一职责原则的英文名称是Single Responsibility Principle,简称是SRP。SRP原则的解释是:There should never be more than one reason for a class to change。定义很简单,即不能存在多于一个导致类变更的原因。简单的说就是一个类只负责一项职责。
在软件设计中,秉承着“高内聚,低耦合”的思想,让一个类仅负责一项职责,如果一个类有多于一项的职责,那么就代表这个类耦合性变高了,这些职责耦合在了一起,这是比较脆弱的设计。因为一旦某一项职责发生了改变,需要去更改代码,那么有可能会引起其他职责改变。所谓牵一发而动全身,这显然是我们所不愿意看到的,所以我们会把这个类分拆开来,由两个类来分别维护这两个职责,这样当一个职责发生改变,需要修改时,不会影响到另一个职责。
需要说明的是单一职责原则不只是面向对象编程思想所特有的,只要是模块化的程序设计,都适用单一职责原则。
关于职责
看到上面所述,或许有人会说这么简单谁不知道。的确,很多程序员即使没有学过设计模式,不知道单一职责原则,在编程的时候,在设计软件时也会有意识的遵循这一原则。因为谁都不希望修改一个地方会引发另外一个地方出现问题,而避免这种问题的最好处理方式就是设计时遵循单一职责原则。但是,我认为单一职责原则的难点是在于职责范围的认定。关于职责的认定是一个仁者见仁智者见智的话题,在实际开发中也会引起程序员之间的争论。有的人认为这些功能方法的实现目的很相似,必须要放在一个类中,有的人认为方法差别很大,必须要分拆成多个类,在多个类里面来实现。
还有职责的扩散问题。软件一开发完上线后并不是一成不变的,随着社会的进步,需求的变更,软件的功能可能要做些维护更改,有时候会遇到职责扩散。所谓的职责扩散就是因为某种原因,职责R被分化为粒度更细的R1和R2。
比如类C只负责一个职责R,这是符合单一职责原则的。但是后来需要把职责R拆分为职责R1和职责R2,那么这时候是否需要死守着单一职责原则,把类C也拆开为C1和C2。接着如果R1又需要细化为R11和R12呢……
我们必须要意识到,一味的遵守单一职责原则,不停的分拆类所付出的开销是很大的。这时候就涉及到平衡的问题,平衡单一职责原则与修改造成的开销。我的观点是如果一个方法逻辑不复杂的情况下,可以修改方法实现,否则要拆分为两个方法,遵循方法级别的单一职责原则;如果一个类方法不多的情况下,可以只增加方法,而不用分拆为多个类,否则要拆分为多个类,遵循类级别的单一职责原则。
遵循单一职责原则的优点
- 降低了类的复杂度。一个类只负责一项职责比负责多项职责要简单得多。
- 提高了代码的可读性。一个类简单了,可读性自然就提高了。
- 提高了系统的可维护性。代码的可读性高了,并且修改一项职责对其他职责影响降低了,可维护性自然就提高了。
- 变更引起的风险变低了。单一职责最大的优点就是修改一个功能,对其他功能的影响显著降低。
作者:李天炜
原文链接:http://tianweili.github.io/blog/2015/02/25/single-responsibility-principle/
转载请注明作者及出处,谢谢。