单一职责原则(SRP)
内聚性:一个模块的组成元素之间的功能相关性。
就一个类而言,应该仅有一个引起它变化的原因。
当需求变化时,该变化会反映为类的职责的变化,如果一个类承担了多于一个的职责,那么引起它变化的原因就会有多个。
如果一个类承担的职责过多,就等于把这些职责耦合在一起。一个职责的变化可能会削弱或抑制这个类完成其他职责的能力。
这种耦合会导致脆弱的设计,当变化发生时,设计会遭受到意想不到的破坏。
什么是职责?
在SRP中,吧职责定义为“变化的原因”。如果你能够想到多于一个的动机去改变一个类,那么这个类就具有多于一个职责。有时,很难注意到这一点,我们习惯于以组的形式去考虑职责。
Modem接口,大多数人认为这个接口非常合理:
public interface Modem { public void dial(String pno); public void hangup(); public void send(char c); public void recv(); }
然而,该接口却显示两个职责(1)连接管理(2)数据通信。
dial和hangup连接处理,send和recv数据通信
这两个职责应该被分开吗?这依赖于应用程序变化的方式。如果应用程序的变化会影响连接函数的签名,那么这个设计就具有僵化性的臭味,因为send和recv的类必须要重新编译。
在这种情况下,这两个职责应该被分离,这样做避免了客户程序和这两个职责耦合在一起。
interface DataChannel { public void send(char c); public void recv(); } interface Connection { public void dial(String pno); public void hangup(); }
另外,如果应用程序的变化方式总会导致这两个职责同时变化,那么久不必分离它们,实际上,分离它们就会具有不必要的复杂性的臭味。
总结
SRP是所有原则中最简单的之一,也是最难正确运用的之一。软件设计真正要做的许多内容,就是发现职责并把那些职责相互分离。