1 定义
就一个类而言,应该仅有一个引起它变化的原因。如果一个类承担的职责过多,就等于把这些职责耦合在了一起。一个职责的变化可能会削弱或者抑制这个类完成其他职责的能力。这种耦合会导致脆弱的(fragile)设计。当一个职责发生变化时,可能会影响其它的职责。另外,多个职责耦合在一起,会影响复用性。例如:要实现逻辑和界面的分离。
2 什么是职责
在SRP中,职责定义为“变化的原因”。如果可以想到多于一个的动机去改变一个类,那么这个类就具有多于一个的职责。
例如: 类A负责两个不同的职责:职责1,职责2。当由于职责1的需求发生时就需要修改A类,有可能会导致原本运行正常A类中的职责2功能发生故障。也就是说职责1和2被耦合在了一起。
现有一个Modem的类
- Modem.java
/**
* 调制解调器
*
* @author 一朝风月
*/
public interface Modem {
/**
* 拨号
*
* @param pno 号码
*/
void dial(String pno);
/**
* 挂机
*/
void hangup();
/**
* 发送消息
*
* @param c 消息
*/
void send(char c);
/**
* 接收消息
*/
void recv();
}
我们发现这个接口里会有两个职责,前两个方法属于连接管理,后两个职责属于数据通信,按照SCP原则的话应该把这个接口拆分成如下两个接口,一个是负责连接管理的,一个是负责数据通信的。
2. Connection.java
/**
* 调制解调器,连接管理
*
* @author 一朝风月
*/
public interface Connection {
/**
* 拨号
*
* @param pno 号码
*/
void dial(String pno);
/**
* 挂机
*/
void hangup();
}
- DataChannel.java
/**
* 调制解调器,数据通信
*
* @author 一朝风月
*/
public interface DataChannel {
/**
* 发送消息
*
* @param c 消息
*/
void send(char c);
/**
* 接收消息
*/
void recv();
}
拆分后的UML如下图所示:
3 结论
SRP是所有原则中最简单的之一,也是最难正确运用的之一。在实践中会自然地把多种职责结合在一起。
软件设计中真正要做的许多内容,就是发现职责并把这些职责相互分离。事实上,其他的设计原则都会以这样或者那样的方式回到这个问题上来。
返回目录