• 概要
@H_301_4@There should never be morethan one reason for a class to change.永远不要让一个类存在一个以上的变更理由。 @H_301_4@如果一个类存在多个改变它的理由,就说明这个类具有多个职责,有需要重新设计该类的必要。
SRP单一职责原则的核心含义:
◇ 一个类有且仅有一个职责。
◇ 如果一个类需要改变,改变它的理由永远只有一个。
一个类必须有且仅有单一职责,这也是单一职责原则命名的由来。 @H_301_4@设计类时要符合单一职责原则的原因:
如果一个类具有一个以上的职责,那么就会有多个不同的原因引起该类变化,而这种变化将影响到该类不同职责的使用者。
◇ 如果一个职责使用了外部类库,则使用另外一个职责的用户却也不得不包含这个未被使用的外部类库。
◇ 某个用户由于某个原因需要修改其中一个职责,另外一个职责的用户也将受到影响,他将不得不重新编译和配置。 @H_301_4@• 职责的划分和类的抽出 @H_301_4@Robert.C Martin给出了一个著名的定义:所谓一个类的一个职责是指引起该类变化的一个原因。
If you can think of more than one motive forchanging a class,then that class has more than one responsibility.
如果你能想到一个类存在多个使其改变的原因,那么这个类就存在多个职责。
这里用一个Modem的例子来说明怎么样进行职责的划分:
interfaceModem { public void dial(String pno); //拨号 public voidhangup(); //挂断 public void send(char c); //发送数据 public charrecv(); //接收数据 }
咋一看,这是一个没有任何问题的接口设计。但事实上,这个接口包含了2个职责:
◇ 第一个是连接管理(dial,hangup
◇ 另一个是数据通信(send,recv)
很多情况下,这2个职责没有任何共通的部分,它们因为不同的理由而改变,被不同部分的程序调用。所以它违反了SRP原则。
我们能发现,对于Modem类有以下两个这样的理由。
◇ 连接方法的変更 ⇒ Modem的変更
◇ 送受信方法的変更 ⇒ Modem的変更
根据这两个理由,我们可以考虑将这个类重新划分成两个职责单一的类
1.连接管理关联的职责类:
Connection {dial,hangup}
2.数据受送信关联的职责类:
DataChannel {send,recv}
@H_301_4@ @H_301_4@• 总结 @H_301_4@Single Responsibility Principle (SRP)从职责(改变理由)的侧面上为我们对类(接口)的抽象的颗粒度建立了判断基准:在为系统设计类(接口)的时候应该保证它们的单一职责性。
1.一个类只有一个引起它变化的原因,否则就应当考虑重构。
2.SRP由引起变化的原因决定,而不由功能职责决定。虽然职责常常是引起变化的轴线,但是有时却未必,应该审时度势。
3.测试驱动开发,有助于实现合理分离功能的设计。
4.可以通过Façade模式或Proxy模式进行职责分离。
@H_301_4@ @H_301_4@一般的情况下、可以按照以下手顺设计符合SRP单一职责原则的类: @H_301_4@1.机能的整理:要划分出有哪些机能。 @H_301_4@2.类的抽出:相似的机能可以作为一个类抽出。 @H_301_4@3.考虑变更的理由:列举出所有能引起类的变更理由。 @H_301_4@4.类的再次划分:如果一个类有多个变更的理由,将这个类分割成单一职责的类。如果多个类具有同一个变更的理由,可以将这几个类作成一个类。