第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. 设计模式原则(1)--Single Responsibility Principle(SRP)--单一职责原则

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

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

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

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

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

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

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

  5. 敏捷软件开发_实例2<四>

    敏捷软件开发_实例2 上一章中对薪水支付案例的用例和类做了详细的阐述,在本篇会介绍薪水支付案例包的划分和数据库,UI的设计. 包的划分 一个错误包的划分 为什么这个包是错误的: 如果对classifi ...

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

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

  7. 【设计模式】单一职责原则(SRP)

    单一职责原则是面向对象原则五大原则中最简单,也是最重要的一个原则, 他的字面定义如下: 单一职责原则(Single Responsibility Principle, SRP): 一个类只负责一个功能 ...

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

    单一职责原则是面向对象原则五大原则中最简单,也是最重要的一个原则, 他的字面定义如下: 单一职责原则(Single Responsibility Principle, SRP): 一个类只负责一个功能 ...

  9. java设计模式学习笔记--单一职责原则

    单一职责原则注意事项和细节 1.降低类的复杂度,一个类只负责一项职责 2.提高可读性,可维护性 3.降低变更引起的风险 4.通常情况下,我们应当遵守单一职责原则,只有逻辑足够简单,才可以在代码级违反单 ...

  10. 设计模式课程 设计模式精讲 3-6 单一职责原则Coding

    1 要点讲解 1.1 需要注意 2 代码演练 2.1 类的单一职责原则demo 2.2 接口的单一职责原则demo 2.3 方法的单一职责原则demo 1 要点讲解 1.1 需要注意 1.1.1 实际 ...

随机推荐

  1. 【Spring】利用AOP来做系统性能监控

    需求: 假设已经有了一些类,现在想统计每个方法调用花了多长时间,该怎么做? 思路: 我第一个想法就是去每个方法执行前后记录一下当前的时间戳,然后相减统计到日志. OK,没问题,那么这样做合理吗? 首先 ...

  2. Node之pm2

    最近在项目中使用了Node,在程序部署的时候直接使用命令:node app.js ,这样我们的程序就可以host起来了,但是只要dos窗口关掉之后node就关闭了,这使得我们很不方便,于是乎发现了pm ...

  3. 四则运算APP(BUG发掘)

    BUG: 1.有几率会出现一样的题目. 2.题目会出现两个一样的答案. 3.做题结束后不能返回主界面或者重新开始. 感想: 1.题目应该按年级分类出题. 2.主界面可以添加更多功能 如自己输入题目数, ...

  4. ASP.NET MVC5--添加验证

    1.在Model类里面添加验证,代码如下: public class Movie { public int ID { get; set; } [StringLength(,MinimumLength= ...

  5. 已超过传入消息(65536)的最大消息大小配额。若要增加配额,请使用相应绑定元素上的 MaxReceivedMessageSize 属性。

    错误:已超过传入消息(65536)的最大消息大小配额.若要增加配额,请使用相应绑定元素上的 MaxReceivedMessageSize 属性. 或者 错误:反序列化操作“GetAllUserData ...

  6. 将HTML5 Canvas的内容保存为图片

    主要思想是借助Canvas自己的API - toDataURL()来实现,整个实现 HTML + JavaScript的代码很简单. 代码如下: <html> <meta http- ...

  7. [CLR via C#]8. 方法

    一.实例构造器和类(引用类型) 类实例构造器是允许将类型的实例初始化为良好状态的一种特殊的方法. 类实例构造器方法在"方法定义元数据表"中始终叫.ctor(代表constructo ...

  8. 第一个app.总结

    前记: 最近想整点外快,但是又没啥子技术,唉,学了一下android,想写点游戏啥的,,唉,可惜,美工,UI始终不行,代码也勉勉强强... 不过总的来说也是收获参半吧,也是有一些新的知识学到了嘛,至少 ...

  9. sql 两列相加存到另一列

    假设表table1有a.b两个列,想生成另一个列为a列值+b列值计算列添加语句如下ALTER TABLE table1ADD c AS a+b

  10. Asp.Net MVC开源论坛中文版

    支持多国语言 支持多种数据库,开盖即饮(因为EF支持),无需安装. 积分 等级 权限 角色 标签 Rss 表情 附件 审核 问答 投票 收藏 日志 排行榜与热点 主题,默认Bootstrap响应式 最 ...