首页 > 代码库 > 单一职责原则

单一职责原则

什么是单一职责原则?

  单一职责原则的英文名称是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呢……

  我们必须要意识到,一味的遵守单一职责原则,不停的分拆类所付出的开销是很大的。这时候就涉及到平衡的问题,平衡单一职责原则与修改造成的开销。我的观点是如果一个方法逻辑不复杂的情况下,可以修改方法实现,否则要拆分为两个方法,遵循方法级别的单一职责原则;如果一个类方法不多的情况下,可以只增加方法,而不用分拆为多个类,否则要拆分为多个类,遵循类级别的单一职责原则。

遵循单一职责原则的优点

  • 降低了类的复杂度。一个类只负责一项职责比负责多项职责要简单得多。
  • 提高了代码的可读性。一个类简单了,可读性自然就提高了。
  • 提高了系统的可维护性。代码的可读性高了,并且修改一项职责对其他职责影响降低了,可维护性自然就提高了。
  • 变更引起的风险变低了。单一职责最大的优点就是修改一个功能,对其他功能的影响显著降低。