第8章 SRP:单一职责原则

  一个类应该只有一个发生变化的原因。

8.1 定义职责

  在SRP中我们把职责定义为变化的原因。如果你想到多于一个的动机去改变一个类,那么这个类就具有多于一个的职责。同时,我们很难注意到这一点。我们习惯于以组的形式去考虑职责。违反SRP的示例代码:

public interface Modem
{
public void Dial(string pno);
public void Hangup();
public void Send(char c);
public char Recv();
}

  大多数人会认为这个接口看起来非常合理。该接口所声明的4个函数确实是调制解调器所具有的功能。

  然而接口中却显示出两个职责。第一个职责是链接管理;第二个职责是数据通信。dial和hangup函数进行调制解调器的连接处理,而send和recv函数进行数据通信。

  这两个职责应该分开吗?这依赖于应用程序变化的方式。如果应用程序的变化会影响连接函数的签名(signature),那么这个设计就具有僵化性的臭味,因为调用send和recv的类必须要重新编译、部署的次数常常会超出我们希望的次数。在这种情况下,这两个职责应该被分离。这样做避免了客户应用程序和这两个职责耦合在一起。

  另一方面,如果应用程序的变化方式总是导致这两个职责同时变化,那么就不必分离它们。实际上,分离它们就会有不必要的复杂性的臭味。

  在此还有一个推论。仅当变化发生时,变化的轴线才具有实际意义。如果没有前兆,那么应用SRP或者任何其他原则都是不明智的。

8.2 分离耦合的职责

  上图中,我把两个职责都耦合进了ModemImplementation类中。这不是所希望的,但是或许是必要的。常常会有一些和硬件或者操作系统的细节有关的原因,迫使我们把不愿耦合在一起的东西耦合在一起。然而,应用的其余部分来说,通过分离它们的接口我们已经解耦了概念。

  我们可以把ModemImplementation类看作是一个杂凑物,或者有缺陷的类。然而,请注意所有的依赖关系都是从它发出的。谁也不需要依赖于它。除了main外,谁也不需要知道它的存在。因此,我们已经把丑陋的部分隐藏起来了。其丑陋性不会泄漏出来,污染应用的其他部分。

8.3 持久化

  

  上图展示了一种常见的违反SRP的情形。Employee类包含了业务规则和对于持久化的控制。这两个职责在大多数情况下绝不应该混合在一起。业务规则往往会频繁地变化,而持久化的方式却不会如此频繁地变化,并且变化的原因也是完全不同的。把业务规则和持久化自系统绑定在一起的做法是自讨苦吃。

  幸运的是,测试驱动的开发实践常常会远在设计出现臭味之前就迫使我们分离这两个职责。然而,如果测试没有迫使这种分离,而僵化性和脆弱性的臭味又很强烈,那么就应该使用FACADE(外观)、DAO(数据访问对象)或者PROXY(代理)模式对设计进行重构,分离这两个职责。

8.4 结论

  SRP是所有原则中最简单的原则之一,也是最难正确运用的原则之一。我们会自然地把职责结合在一起。软件设计真正要做的许多工作,就是发现职责并把那些职责相互分离。事实上,我们将要论述的其余原则都会以这样或那样的方式回到这个问题上。

摘自:《敏捷软件开发:原则、模式与实践(C#版)》Robert C.Martin    Micah Martin 著

转载请注明出处:

作者:JesseLZJ
出处:http://jesselzj.cnblogs.com

敏捷软件开发——第8章 SRP:单一职责原则的更多相关文章

  1. 六大设计原则(一)SRP单一职责原则

    单一职责原则SRP(Single reponsibility principle) BO(Business Object):业务对象 Biz(Business Logic):业务逻辑 SRP最简单的例 ...

  2. 设计模式原则(1)--Single Responsibility Principle(SRP)--单一职责原则

    1.定义: 不要存在多于一个导致类变更的原因.通俗的说,即一个类只负责一项职责.  2.使用场景: 如果类A有两个职责:d1,d2.当职责d1需要修改时,可能会导致原本运行正常的职责d2功能产生问题. ...

  3. 面向对象设计之SRP(单一职责)原则

    SRP设计原则面向对象类设计的第一个原则,最优先考虑的因素 一个类应该有且仅有一个职责.所谓一个类的职责是指引起该类变化的原因,如果一个类具有一个以上的职责,那么就会有多个不同的原因 引起该类变化,其 ...

  4. 《敏捷软件开发-原则、方法与实践》-Robert C. Martin读书笔记(转)

    Review of Agile Software Development: Principles, Patterns, and Practices 本书主要包含4部分内容,这些内容对于今天的软件工程师 ...

  5. 单一职责原则(Single Responsibility Principle)

    单一职责原则(SRP:The Single Responsibility Principle) 一个类应该有且只有一个变化的原因. There should never be more than on ...

  6. 敏捷软件开发:原则、模式与实践——第8章 SRP:单一职责原则

    第8章 SRP:单一职责原则 一个类应该只有一个发生变化的原因. 8.1 定义职责 在SRP中我们把职责定义为变化的原因.如果你想到多于一个的动机去改变一个类,那么这个类就具有多于一个的职责.同时,我 ...

  7. 敏捷软件开发:原则、模式与实践——第12章 ISP:接口隔离原则

    第12章 ISP:接口隔离原则 不应该强迫客户程序依赖并未使用的方法. 这个原则用来处理“胖”接口所存在的缺点.如果类的接口不是内敛的,就表示该类具有“胖”接口.换句话说,类的“胖”接口可以分解成多组 ...

  8. 敏捷软件开发:原则、模式与实践——第14章 使用UML

    第14章 使用UML 在探索UML的细节之前,我们应该先讲讲何时以及为何使用它.UML的误用和滥用已经对软件项目造成了太多的危害. 14.1 为什么建模 建模就是为了弄清楚某些东西是否可行.当模型比要 ...

  9. 敏捷软件开发:原则、模式与实践——第10章 LSP:Liskov替换原则

    第10章 LSP:Liskov替换原则    Liskov替换原则:子类型(subtype)必须能够替换掉它们的基类型(base type). 10.1 违反LSP的情形 10.1.1 简单例子 对L ...

随机推荐

  1. Go Example--限速

    package main import ( "fmt" "time" ) func main() { requests := make(chan int, 5) ...

  2. MSP430F2272 Flash

    The collected information is listed below during flash of MSP430 development. MSP430F2272: 32KB + 25 ...

  3. Apache和Nginx负载均衡集群及测试分析

    一.应用场景介绍 本文主要是介绍Apache和Tomcat在Linux环境下的安装讲解以及AJP协议动静分离负载均衡的实现,以及与Nginx负载性能比较.联网安装较为简单,故此处只说脱机的Linux环 ...

  4. Bartender 使用 Excel xlsx 数据库时出现 0x800A0E7A

    Bartender 使用 Excel 数据库时出现 0x800A0E7A 这是因为没有装 数据库驱动的原因. 安装微软的驱动就可以. 注意是安装 32 位的驱动. https://www.micros ...

  5. i++和++i的笔试题

    i = ++i + i++ + i++ + i++; 把每个 i++或者++i看作一个部分,他们的分别再下一个 i++或者++i改变,中途赋值的话,就返回这个部分的值 来自:https://www.j ...

  6. 127.0.0.1 localhost 0.0.0.0 回环地址区别

    127.0.0.1:一般认为是本机ip,这个没错.但是本机ip不只是 127.0.0.1 而是所有回环地址. 回环地址: 包括127.0.0.1在内的 所有 指向本机的地址.范围是  127.0.0. ...

  7. laravel 一表關聯二表,二表關聯三表,通過一表controller拿三表數據

    model 一表關聯二表 public function ordercode() { return $this->hasOne(\App\Models\OrderCode::class,'id' ...

  8. JFrame背景色设置

    JFrame对象本身是包含Pane的,一般我们在往JFrame中添加组件时,都加在了ContentPane中,这个可以通过JFrame的成员方法getContentPane()取出来.所以如果设置JF ...

  9. 9、后记:公司管理经验总结 - CEO之公司管理经验谈

    在前期的公司管理经验谈中,笔者已经将相关考虑到的公司经营的问题做了一些思考和总结,希望能够对广大的想自己创业的IT从业者们提供参考. 这里提供一个连接,能够对广大的初期创业者们有个开公司流程的帮助:h ...

  10. paramiko 实现ssh登录和sftp登录

    简单ssh登录 import paramiko ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddP ...