首先是定义
单一职责原则:一个类应该只有一个发生变化的原因
英文名叫Single Responsibility Principle,以下简称为SRP
下面我们从三本著作中去解读这个单一职责
这三本著作分别是《深入浅出面向对象分析与设计》、《设计模式解析》和《敏捷开发:原则、模式与实践》。
深入浅出面向对象分析与设计
首先他对SRP的解读稍有不同:
单一职责原则:系统里的每一个对象应该具有单一职责,所有对象的服务都应该聚焦在实现该职责上。
且他认为
内聚性是SRP的另一个名称。如果你的类是高内聚的,就表示你在正确的使用SRP。
为什么要强调他这里说的内聚性呢?因为在《敏捷》书中,他认为如果类的接口不是内聚的,那么就违反了接口隔离原则
(在百度百科里,他认为单一职责是基于内聚性提出的。图如下)
在最后他提出了一个判断是否是单一职责的办法:
写下一个式子:
the itself,其中第一个单词写类名,第二个单词写方法名,如果有参数的话在方法后跟上参数
我们举这样一个例子,调制调解器,就是光猫,可以拨号挂断,发数据和接收数据。
用《深入浅出》里的方法这个符合单一职责模式。但是在《敏捷》里就不符合了,这里在后面讲。
下面来看《设计模式解析》
设计模式解析
他将对象看做是具有责任的东西。每个对象包含一组职责,这个在之前如何理解一个类——单一职责原则中已经说了很多,这里不再赘述
最后一个是要将《敏捷》书
敏捷开发:原则、模式与实践
书中也说了来自于内聚性,但是在他的理解里,上述光猫的例子是违反SRP的。
他认为拨号和挂断属于连接管理,接受和发送属于数据通信。
我们把前者认为是A职责,后者是B职责,这两种职责是否应该被分开取决于两者是否经常同时变化。
如果在A职责出现变动时,B职责也要同时变动,那么两个可以不用分开,否则的话就需要被分开。
- 假设此时二者是同时变化的,而分开了
那么带来的影响是:我在修改A职责所在的类时还要去审查B职责所在类的正确改动,显然是不好的。 - 假设此时二者是非同时变化的,没有分开
那么带来的影响是:(书中所说)其他不需要变化的方法需要重新部署编译,会增加部署的次数。另一方面我觉得是因为二者可以独立变化。
最终的解决方案是将两个独立变化的职责分到了连接管理类和数据通信类,然后新建一个光猫类组合这两个类,外部依赖光猫类去调用。
提到了另一个例子是MVC
如Person类,从某种角度来看,Person的持久化(dao层)职责和业务(Service)职责都属于Person的职责,但是显然是不能放在一起的,原因是持久化层几乎不会变化,而业务层复杂多变改动大。持久化层隔离开后复用性高。
最后文末提到了外观模式和代理模式,这两个模式可以用于分离职责。
PS《敏捷》中提及的是否同步变化在其他两处没有特别强调,相对宽松,很多地方没有独立的讲接口隔离原则。
原文地址:http://blog.51cto.com/13985113/2311418
时间: 2024-10-29 19:11:23