Single Resposebility Principle,简称 SRP。

存在争议

对职责的定义。什么是类的职责?怎么划分类的职责?

定义

应该有且仅有一个原因引起类的变更。

There should never be more than one reason for a class to change.

例子

public interface IPhone {
	// 拨通电话
	public void dial(String phoneNumber);
	
	// 通话
	public void chat(Object o);
	
	// 通话完毕,挂电话
	public void hangup();

}

这个接口接近于完美,但还不是。

IPhone包含了两个职责:

协议管理

负责拨号接通和挂机。 协议接通的变化会引起这个接口或者实现类的变化吗?电信协议或者网通协议?

数据传送

数据的传送。数据传送的变化会引起这个接口或实现类的变化吗?通话数据或网络数据?

改造后方案

优势:

完全满足了单一职责原则的要求,接口职责分明,结构清晰。

劣势:

过于复杂。而且ConnectionManagerDataTransfer组合一起才能用,有共同的声明周期。

引起类间耦合过重、类的数量增加等问题,人为地增加了设计的复杂性。

再次改造后

优势:

简单,接口职责明确。

接口满足单一职责的要求,满足面向接口编程的要求。

劣势:

类没有满足单一职责的要求

单一职责原则的好处

  • 类的复杂性降低,实现什么职责都有清晰明确的定义

  • 可读性提高,复杂性降低

  • 可维护性提高

  • 变更引起的风险降低。

    一个接口修改只对相应的实现类有影响,这对系统的扩展项、维护性有很大的帮助

单一职责原则的弊端

  • 引起类的剧增,给维护带来非常多的麻烦
  • 过分细分类的职责也会人为地增加系统的复杂性
  • 在项目中很难得到体现

TIPS:

单一职责原则提出了一个编写程序的标准,用“职责”或“变化原因”来衡量接口或类设计得是否优良,但“职责”和“变化原因”都是不可度量的,因项目而异,因环境而异。

适用

适用于接口、类、方法。

不要定义粗粒度的方法,不要让别人猜测这个方法可能是用来处理什么逻辑的。

接口一定要做到单一职责

类的设计尽量做到只有一个原因引起变化。


读《设计模式之禅》第一章 单一职责原则