敏捷软件开发:原则、模式与实践——第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:单一职责原则的更多相关文章
- 设计模式原则(1)--Single Responsibility Principle(SRP)--单一职责原则
1.定义: 不要存在多于一个导致类变更的原因.通俗的说,即一个类只负责一项职责. 2.使用场景: 如果类A有两个职责:d1,d2.当职责d1需要修改时,可能会导致原本运行正常的职责d2功能产生问题. ...
- 六大设计原则(一)SRP单一职责原则
单一职责原则SRP(Single reponsibility principle) BO(Business Object):业务对象 Biz(Business Logic):业务逻辑 SRP最简单的例 ...
- 面向对象设计之SRP(单一职责)原则
SRP设计原则面向对象类设计的第一个原则,最优先考虑的因素 一个类应该有且仅有一个职责.所谓一个类的职责是指引起该类变化的原因,如果一个类具有一个以上的职责,那么就会有多个不同的原因 引起该类变化,其 ...
- 《敏捷软件开发-原则、方法与实践》-Robert C. Martin读书笔记(转)
Review of Agile Software Development: Principles, Patterns, and Practices 本书主要包含4部分内容,这些内容对于今天的软件工程师 ...
- 敏捷软件开发_实例2<四>
敏捷软件开发_实例2 上一章中对薪水支付案例的用例和类做了详细的阐述,在本篇会介绍薪水支付案例包的划分和数据库,UI的设计. 包的划分 一个错误包的划分 为什么这个包是错误的: 如果对classifi ...
- 单一职责原则(Single Responsibility Principle)
单一职责原则(SRP:The Single Responsibility Principle) 一个类应该有且只有一个变化的原因. There should never be more than on ...
- 【设计模式】单一职责原则(SRP)
单一职责原则是面向对象原则五大原则中最简单,也是最重要的一个原则, 他的字面定义如下: 单一职责原则(Single Responsibility Principle, SRP): 一个类只负责一个功能 ...
- 【面向对象设计原则】之单一职责原则(SRP)
单一职责原则是面向对象原则五大原则中最简单,也是最重要的一个原则, 他的字面定义如下: 单一职责原则(Single Responsibility Principle, SRP): 一个类只负责一个功能 ...
- java设计模式学习笔记--单一职责原则
单一职责原则注意事项和细节 1.降低类的复杂度,一个类只负责一项职责 2.提高可读性,可维护性 3.降低变更引起的风险 4.通常情况下,我们应当遵守单一职责原则,只有逻辑足够简单,才可以在代码级违反单 ...
- 设计模式课程 设计模式精讲 3-6 单一职责原则Coding
1 要点讲解 1.1 需要注意 2 代码演练 2.1 类的单一职责原则demo 2.2 接口的单一职责原则demo 2.3 方法的单一职责原则demo 1 要点讲解 1.1 需要注意 1.1.1 实际 ...
随机推荐
- Android学习笔记之树形菜单的应用...
PS:终于考完试了,总算是解脱了...可以正式上手项目开发了.... 学习内容: 1.掌握如何使用树形菜单... 对知识点进行一下补充...居然忘记了去学习树形菜单...不过在这里补上... Ex ...
- nginx的部署与发布
1.在http://nginx.org/en/download.html下载nginx.tar.gz包. 2.上传发送到服务器(wcp工具) 3.用tar -xf命令解压gz包 4.[配置安装变量]: ...
- 如何根据iframe内嵌页面调整iframe高宽续篇
接着昨天的工作 如何根据iframe内嵌页面调整iframe高宽 来说,按照文章中说的第二种方法实现代码如下: 实现 A.com/detail/view 页面的iframe代码如下: <ifra ...
- [JS] JavaScript由浅入深(1) 基本特性
1.全局变量的特性: 在函数体内直接写的变量(未用var标志)自动升级为全局变量. (function func() { i = 100; }()); alert(i); 非常不建议不写var. va ...
- sprint3 总结
sprint3 本次的主要任务是找项目中的bug,并与客户不断地沟通以满足客户的要求.队友主要负责找项目中的bug或提出一些建议.我主要是负责与客户沟通和修复bug.总的来说进展还算顺利. 团队贡献分 ...
- 数论 - 欧拉函数模板题 --- poj 2407 : Relatives
Relatives Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 11372 Accepted: 5544 Descri ...
- Unity实现滑页效果(UGUI)
简介 项目需要...直接展示效果吧: 原理 使用UGUI提供的ScrollRect和ScrollBar组件实现基本滑动以及自己控制每次移动一页来达到滑页的效果. 实现过程 1.创建两个panel,上面 ...
- Redis 3.2.100 Windows 32位下载
因为公司的老服务器用的是Windows 2008 32位,不得不安装Redis32位.可在微软的Github上有64位的MSI安装包,前天开始在不同的群里寻找32位的安装包,一直没找到,索性自己下载源 ...
- 【JS复习笔记】07 复习感想
好吧,其实<JavaScript语言精粹>后面还简单介绍了代码风格,优美特性,以及包含的毒瘤.糟粕. 但我很快就看完了,发现其实都在前面讲过了,所以就不写了. 至今为止已经算是把JavaS ...
- css中inline、block、inline-block的区别
http://www.cnblogs.com/fxair/archive/2012/07/05/2577280.html display:inline就是将元素显示为块级元素. block元素的特点是 ...