单一职责原则

  前言:据说设计模式是区别程序员与软件设计师的标准之一。其实在编程学习初期就接触过设计模式,但是都没有写过多少代码是领悟不到设计模式真正的威力和必要性的。现在自认为也实践过不少段时间了,是时候总结一下设计模式。不知谁说过没有写过十万行以上代码别谈设计模式,虽然略显夸张,但是还是很有道理的。只有自己亲身经历过一些编写设计垃圾代码,才会深刻理解设计模式真正的意义所在。设计模式都是前辈大牛们在无数次实践中总结出来的,我辈自然要站在巨人肩膀上,实行拿来主义并消化使用之。

1、问题的由来

  初学者在编程的时候可能一开始会有这样的经历,使用一个类来实现很多的功能,新添加的甚至不相关的功能都放在一个类里来实现,煮成了一锅大杂烩,往往使得某个类包罗万象,无所不能。可能刚开始实现功能比较简单,这样做不会引发什么特别大的问题。但是随着项目复杂度的提升,各种不相关的实现代码耦合在一起,一旦有功能的更改或增删,修改的代码很可能会导致其他功能的正常运行。这种编程方式显然是不可取的,也就是违背了所谓的单一职责原则。

2、什么是单一职责原则?

  单一职责原则的英文名称是Single Responsibility Principle,简称是SRP。SRP原则的解释是:There should never be more than one reason for a class to change。定义很简单,即不能存在多于一个导致类变更的原因。简单的说就是一个类只负责一项职责。

  在软件设计中,秉承着“高内聚,低耦合”的思想,让一个类仅负责一项职责,如果一个类有多于一项的职责,那么就代表这个类耦合性变高了,这些职责耦合在了一起,这是比较脆弱的设计。因为一旦某一项职责发生了改变,需要去更改代码,那么有可能会引起其他职责改变。所谓牵一发而动全身,这显然是我们所不愿意看到的,所以我们会把这个类分拆开来,由两个类来分别维护这两个职责,这样当一个职责发生改变,需要修改时,不会影响到另一个职责。

  需要说明的是单一职责原则不只是面向对象编程思想所特有的,只要是模块化的程序设计,都适用单一职责原则。

3、关于职责

  看到上面所述,或许有人会说这么简单谁不知道。的确,很多程序员即使没有学过设计模式,不知道单一职责原则,在编程的时候,在设计软件时也会有意识的遵循这一原则。因为谁都不希望修改一个地方会引发另外一个地方出现问题,而避免这种问题的最好处理方式就是设计时遵循单一职责原则。但是,我认为单一职责原则的难点是在于职责范围的认定。关于职责的认定是一个仁者见仁智者见智的话题,在实际开发中也会引起程序员之间的争论。有的人认为这些功能方法的实现目的很相似,必须要放在一个类中,有的人认为方法差别很大,必须要分拆成多个类,在多个类里面来实现。

  还有职责的扩散问题。软件一开发完上线后并不是一成不变的,随着社会的进步,需求的变更,软件的功能可能要做些维护更改,有时候会遇到职责扩散。所谓的职责扩散就是因为某种原因,职责R被分化为粒度更细的R1和R2。

  比如类C只负责一个职责R,这是符合单一职责原则的。但是后来需要把职责R拆分为职责R1和职责R2,那么这时候是否需要死守着单一职责原则,把类C也拆开为C1和C2。接着如果R1又需要细化为R11和R12呢……

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

4、遵循单一职责原则的优点

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

热评文章