面向对象程序设计的六大原则(1)-单一职责原则

时间:2021-02-19 19:11:09

前言

在网上有很多文章讲这是“设计模式六大原则”,也有人讲这是“面向对象程序设计的六大原则”,我更倾向于后者。假设一个程序员不懂设计模式或者一个简单的、开发周期极短的程序可以牺牲设计模式带来的可扩展性, 而避免设计模式带来的 复杂性时,他在做面向对象设计的时候依然需要这些原则,因此本质上这并不是设计模式的六大原则,而是面向对象设计的六大原则。当然我们无论是在学习面向对象分析与设计,还是在学习设计模式前,都需要知道这些原则,从学习设计模式的角度上来看,叫做“设计模式六大原则”也不算错。

这六个原则常被叫做SOLID原则:
单一职责原则,SRP(Single Responsibility Principle)
开放-关闭原则,OCP(Open-Close Principle)
里氏替换原则,LSP(Liskov Substitution Principle)
接口隔离原则,ISP(Interface Segregation Principle)
依赖倒置原则,DIP(Dependence Inversion Principle)
最少知识原则,LKP(Least Knowledge Principle),又称迪米特法则,LOD(Law Of Demeter)


本文主要阐述"单一职责原则“(Single Resonpisibility Principle):

定义:

就一个类而言,应该仅有一个引起它变化的原因。通俗点地说就是不存在多个原因使得一个类发生变化,也就是说一个类只负责一种职责工作。

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

问题由来:

类T负责两个不同的职责:职责P1,职责P2。当由于职责P1需求发生改变而需要修改类T时,有可能会导致原本运行正常的职责P2功能发生故障。

解决方案:

       遵循单一职责原则。分别建立两个类T1、T2,使T1完成职责P1功能,T2完成职责P2功能。这样,当修改类T1时,不会使职责P2发生故障风险;同理,当修改T2时,也不会使职责P1发生故障风险。


关于职责:

单一职责原则的难点是在于职责范围的认定。关于职责的认定是一个仁者见仁智者见智的话题,在实际开发中也会引起程序员之间的争论。有的人认为这些功能方法的实现目的很相似,必须要放在一个类中,有的人认为方法差别很大,必须要分拆成多个类,在多个类里面来实现。

还有职责的扩散问题。软件一开发完上线后并不是一成不变的,随着社会的进步,需求的变更,软件的功能可能要做些维护更改,有时候会遇到职责扩散。所谓的职责扩散就是因为某种原因,职责R被分化为粒度更细的R1和R2。比如类C只负责一个职责R,这是符合单一职责原则的。但是后来需要把职责R拆分为职责R1和职责R2,那么这时候是否需要死守着单一职责原则,把类C也拆开为C1和C2。接着如果R1又需要细化为R11和R12呢……在程序已经写好的情况下,一味的遵守单一职责原则,不停的分拆类所付出的开销是很大的。这时候就涉及到平衡的问题,平衡单一职责原则与修改造成的开销的平衡。在职责扩散到我们无法控制的程度之前,立刻对代码进行重构。

遵循单一职责的优点有:

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