敏捷软件开发——第8章 SRP:单一职责原则
第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:单一职责原则的更多相关文章
- 六大设计原则(一)SRP单一职责原则
单一职责原则SRP(Single reponsibility principle) BO(Business Object):业务对象 Biz(Business Logic):业务逻辑 SRP最简单的例 ...
- 设计模式原则(1)--Single Responsibility Principle(SRP)--单一职责原则
1.定义: 不要存在多于一个导致类变更的原因.通俗的说,即一个类只负责一项职责. 2.使用场景: 如果类A有两个职责:d1,d2.当职责d1需要修改时,可能会导致原本运行正常的职责d2功能产生问题. ...
- 面向对象设计之SRP(单一职责)原则
SRP设计原则面向对象类设计的第一个原则,最优先考虑的因素 一个类应该有且仅有一个职责.所谓一个类的职责是指引起该类变化的原因,如果一个类具有一个以上的职责,那么就会有多个不同的原因 引起该类变化,其 ...
- 《敏捷软件开发-原则、方法与实践》-Robert C. Martin读书笔记(转)
Review of Agile Software Development: Principles, Patterns, and Practices 本书主要包含4部分内容,这些内容对于今天的软件工程师 ...
- 单一职责原则(Single Responsibility Principle)
单一职责原则(SRP:The Single Responsibility Principle) 一个类应该有且只有一个变化的原因. There should never be more than on ...
- 敏捷软件开发:原则、模式与实践——第8章 SRP:单一职责原则
第8章 SRP:单一职责原则 一个类应该只有一个发生变化的原因. 8.1 定义职责 在SRP中我们把职责定义为变化的原因.如果你想到多于一个的动机去改变一个类,那么这个类就具有多于一个的职责.同时,我 ...
- 敏捷软件开发:原则、模式与实践——第12章 ISP:接口隔离原则
第12章 ISP:接口隔离原则 不应该强迫客户程序依赖并未使用的方法. 这个原则用来处理“胖”接口所存在的缺点.如果类的接口不是内敛的,就表示该类具有“胖”接口.换句话说,类的“胖”接口可以分解成多组 ...
- 敏捷软件开发:原则、模式与实践——第14章 使用UML
第14章 使用UML 在探索UML的细节之前,我们应该先讲讲何时以及为何使用它.UML的误用和滥用已经对软件项目造成了太多的危害. 14.1 为什么建模 建模就是为了弄清楚某些东西是否可行.当模型比要 ...
- 敏捷软件开发:原则、模式与实践——第10章 LSP:Liskov替换原则
第10章 LSP:Liskov替换原则 Liskov替换原则:子类型(subtype)必须能够替换掉它们的基类型(base type). 10.1 违反LSP的情形 10.1.1 简单例子 对L ...
随机推荐
- mac电脑读写NTFS格式的移动硬盘命令
diskutil info /Volumes/SAMSUNG | grep UUID echo "UUID=38EBE5E4-016F-44B7-9D55-BB4AF6DC3E1D none ...
- Go Example--方法
package main import "fmt" //定义结构体 type rect struct { width,height int } //定义结构体指针的方法 func ...
- 找工作String类(重点,背诵)(本质是一个类)
一个顶层设计者眼中只有2个东西接口,类(属性,方法) 无论String 类 , HashMap实现类 , Map接口 String str = "Hello" ; // 定义 ...
- CSVN部署安装,实现web管理svn
系统环境:centos7最小化安装 下载这个文件并解压 https://pan.baidu.com/s/1miwdBc8 tar zxvf jdk-8u91-linux-x64.gz mv jdk1. ...
- Spring定时器corn表达式详解
1.结构 Spring定时器corn表达式详解 2.各字段的含义 字段 允许值 允许的特殊字符 秒 0~59 - * / 分 0~59 - * / 小时 0~23 - * / 日期 1~31 - * ...
- 你不知道的JavaScript(上卷) (Kyle Simpson 著)
第一部分 作用域和闭包 第1章 作用域是什么 (已看) 1.1 编译原理 1.2 理解作用域 1.2.1 演员表 1.2.2 对话 1.2.3 编译器有话说 1.2.4 引擎和作用域的对话 1.2.5 ...
- 用express快速写一个hello world
首页要具备 node.js环境, npm环境 创建一个目录, 然后进入此目录作为工作目录 mkdir myapp cd myapp 通过npm init 创建一个package.json文件 npm ...
- Kubernetes 知识点
自己总结的 Kubernetes 的各模块(待补充) 各模块包含关系: namespace => node => pod => container table th:first-of ...
- web 对接 platform
一个项目拆成web和platform,web不对接数据库,只调用各个platform,每个平台负责出一个httpclient的client-jar包,封装好curd方法给web端调用,入参和出参用ja ...
- cat命令详解
命令cat cat 命令用于连接文件并打印到标准输出设备上 语法格式: cat [-AbeEnstTuv] [--help] [--version] fileName 参数说明: -n 或 --num ...