单一职责原则的概念
一个类被改变的原因不能超过一个,也就是说,一个类只有一个职责,如果职责过多,代码就会臃肿,可读性更差,也更难以维护。其实上单一职责原则和接口隔离原则有一定的关系,接口隔离以后,职责就单一了,实现这个接口的类的职责自然也就单一了。但是接口隔离关注的是抽象层,单一职责关注的是两者兼而有之,偏重于实现。
为什么要遵守单一职责原则
- 提高类的可维护性和可读写性
一个类的职责少了,复杂度降低了,代码就少了,可读性也就好了,可维护性自然就高了。
- 提高系统的可维护性
系统是由类组成的,每个类的可维护性高,相对来讲整个系统的可维护性就高。当然,前提是系统的架构没有问题。
- 降低变更的风险
一个类的职责越多,变更的可能性就更大,变更带来的风险也就越大。
如何遵守单一职责原则
合理的职责分解
相同的职责放到一起,不同的职责分解到不同的接口和实现中去,这个是最容易也是最难运用的原则,关键还是要从业务出发,从需求出发,识别出同一种类型的职责。举个例子:人的行为分析,包括了生理、生活和工作等行为的分析,生理行为包括吃、跑、睡等行为,生活行为包括穿衣等行为,工作行为包括上下班,开会等行为,如下图所示:
图1 人类行为分析示例
人类的行为分成了三个接口:生理行为接口、工作行为接口和生活行为接口,以及三个实现类。如果都用一个实现类来承担这三个接口的职责,就会导致代码臃肿,不易维护,如果以后再加上其他行为,例如学习行为接口,将会产生变更风险。
最佳实践
在实际工作中,有一个经常会用到的设计模式,DAO模式,又叫数据访问对象,里面定义了数据库中表的增、删、改、查操作,按照单一职责原则,为什么不把增、删、改、查分别定义成四种接口?这是因为数据库的表操作,基本上就是这四种类型,不可能变化,所以没有必要分开定义,反而经常变化的是数据库的表结构,表结构一变,这四种操作都要跟着变。所以通常我们会针对一张表实现一个DAO,一张表就代表一种类型的职责。
开放-封闭原则概念
开放封闭原则(OCP,Open Closed Principle):软件实体应该是可扩展,而不可修改的;也就是说,对扩展是开放的,而对修改是封闭的。
OCP主要体现在两个方面:
(1)对扩展开放,意味着有新的需求或变化时,可以对现有代码进行扩展以适应新的情况。
(2)对修改封闭,意味着类一旦设计完成,就可以独立完成其工作而不要对类进行任何修改
抽象编程
对于软件设计者来说,必须在不需要对原有的系统进行修改的情况下,实现灵活的系统扩展,如何做到呢?只有依赖于抽象。实现开放封闭的核心思想就是对抽象编程,而不是具体编程,因为抽象相对稳定。让类依赖于固定的抽象,对修改就是封闭的;通过面向对象的继承和多态,可以实现对抽象体的继承,通过覆写其方法来改变固有行为,实现新的扩展方法。
开发-封闭原则是面向对象设计的核心所在。遵循这个原则可以带来面向对象技术所声称的巨大好处,也就是可维护、可扩展、可复用、灵活性好。开发人员应该仅对程序中呈现出频繁变化的那部分做出抽象,然而, 对于应用程序中的每个部分都刻意地进行抽象, 同样不是一个好主意。拒绝不成熟的抽象和抽象本身一样重要。