单一职责原则:就一个类而言,应该仅有一个引起他变化的原因。
1 一个老师类的例子
或者说在外部看来,一个类只应该能看到它的类的相关功能。如老师类只应该负责教授知识,备课,但是不应该负责开车。
切合实际的说一个TaskService类不应该包含处理时间的类,他可以是private的,但是肯定不能是public的。
这里引出另一个角度
2 如何看待一个类?
2.1通常的看法
通常的看法是,类是由成员属性和成语方法组成的数据结构
或者是现实事物的抽象
如对现实中的人抽象出Person,他具备人的基本属性和基本行为
2.2另外一个角度
但是另外一个角度来看,类是一组职责的集合。类负责他所代表的抽象的职责。
如老师类,就是上课,下课,教书,备课等职责的集合,他对外提供这些接口。姓名年龄这些通常是private封装的。
举日常开发的例子
如任务类,就是查看任务,发布任务,撤回任务,处理任务,完成任务,关闭任务等职责集合。
虚线表示依赖关系,可以认为是使用关系,任务服务类依赖于任务实体类。
如果这里面有个时间处理的方法,那么这个方法肯定是不应该对外public的,如果这个方法比较独立的话,可以封装在日期类中,再通过依赖引入进来。
3 高内聚低耦合
提到单一职责的时候经常提到高内聚低耦合。
内聚性是 类中操作之间联系的紧密程度。
低内聚就是很多功能互不相关,比如时间处理功能和上课功能,就是风马牛不相及的两个功能。高内聚就是联系紧密。
耦合性是 类之间联系的紧密程度。
或者说依赖程度。低耦合就是互相之间的依赖小。
低耦合,首先所有类都负责自己的职责,不同职责由不同类去维护,所以类与类之间的耦合是低的
高内聚,一系列职责由单个类去维护,所有相似的职责内聚在一个类中,这个就是高内聚
一类职责应该集中在一个类中,而不是分散在不同的类中,而不同的职责应该准确划分到不同的类中。
高内聚低耦合的一个反面例子是我在维护的一个老项目。。
一个功能的几个部分被分在了不同的地方,sql在jsp上能看到,没有控制层,一个方法缠缠绕绕出现在了多个类中,而且这个划分的几个部分大多数是没有复用性的。
我们常说有的框架重,让开发者的类和框架类耦合在了一起,开发者的类必须继承框架的某个基类,一旦基类进行了版本升级,那么可能对整个系统都造成影响。
问答部分
Q 我有一个任务类,它有一个发布任务和撤回任务,他是不是单一职责的
A:是的,这两个都属于任务类的职责。
Q 单一职责是仅有一个引起类变化的原因,这里发布任务和撤回任务有变动的话类不是都要变动吗
A:原因是指一系列职责。
Q 如果任务类里包含了一个对外开放的时间处理接口,这个任务类是单一职责吗
A:不是,时间不属于任务处理系列的职责,他应该被设置成private或者放到DateUtil中。
Q 任务处理类中定义时间接口有什么坏处吗
A:
- 首先时间处理不属于任务处理类的职责
- 其次时间处理处理接口放在任务处理类中,正常情况下不会把所有时间处理的接口都放在任务处理类里,那么时间处理的职责就分散在了不同的类中,违反了高内聚;由于时间处理接口分布在不同的类中,这些类的职责耦合在了一起,违反了低耦合
- 当第三方调用任务处理类的时候会不明所以,为什么这里会有一个时间接口,不确定这个方法能不能调用,后期会不会有改动。
- 一旦时间接口改动,要考虑到是否影响到任务类中的其他接口,需要考虑很多,而如果内聚在时间处理类中,相对影响要小。
如果用任务处理类和时间接口做例子比较不明显,我们换下面这个例子就立马可以发现问题了,他们本质是一个问题,只是错误程度不同:
在老师类中定义一个清除系统缓存的接口
原文地址:http://blog.51cto.com/13985113/2310893