一、定义

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

二、为什么要使用SRC

  因为每一个职责都是变化的一个轴线。当需求变化时,这种变化就会反映为类的职责的变化。如果一个类承担了多于一个的职责,那么引起它变化的原因就会有多个。

  如果一个类承担的职责过多,就等于把这些职责耦合在了一起。一个职责的变化可能会消弱或抑制这个类完成其他职责的能力。这种耦合会导致脆弱的设计,当变化发生时,设计会遭到意想不到的破坏。

三、案例演示

  考虑图中的设计。

  

  Rectangle类具有两个方法,一个方法把矩形绘制到屏幕上,另一个方法则是计算矩形的面积。 现在有两个应用程序使用Rectangle类。一个是利用Rectangle计算矩形面积,但不需要绘制矩形;另一个应用程序可能会绘制矩形,也可能计算面积。

  这个设计违反了单一职责原则。Rectangle类具有两个职责。第一个职责提供了矩形面积的计算;第二个职责提供了矩形绘制。 对于SRC的违反导致了一些严重的问题。

  对于这个违反了SRC的程序有以下几点问题:

  首先,我们必须在左侧的程序中包含进GUI代码,即使我们是不需要的。

  其次,如果右侧程序的改变导致了Rectangle的改变,那么这个改变会迫使我们重新构建、测试和部署左侧的程序。

   一个较好的设计就是把这两个职责分离到如下图所示的两个完全不同的类中。这个设计把Rectangle类中进行计算的部分移到了GeometricRectangle类中。现在矩形绘制方法的变化不会影响到左侧的程序。

  

四、什么是职责

  在SRC中,我们把职责定义为变化的原因

  如果你能够想到多于一个的动机去改变一个类,那么这个类就具有多于一个的职责。

  有时,我们很难注意到这一点,我们习惯于以组的形式去考虑职责。 例如,下面的Modem接口,大多数人认为这个接口非常合理。该接口所声明的4个方法确实是调制解调器所具有的功能 。

public interface Modem
{
public void Dial(string pno); //连接
public void Hangup(); //断开
public void Send(char c); //发送
public char Recv(); //接收
}

  然而,该接口中却显示出两个职责。第一个职责是连接管理;第二个职责是数据通信。

  这两个职责需要分开吗?

  这依赖于应用程序变化的方式。如果应用程序的变化会影响到连接管理方法的签名,那么这个设计就具有僵化性,因为调用send和recv的类必须重新编译、部署。在这种情况下,这两个职责应该被分离,如下图所示。

  

  另一方面,如果应用程序的变化方式总是导致这两个职责同时变化,那就不必分离它们。

  记住这么一个结论,仅当变化发生时,变化的轴线才具有实际意义。如果没有征兆,那么应用SRP或者任何其它原则都是不明智的。

五、分离耦合的职责

  请注意,在上图中,把两个职责都耦合进了ModemImplementation类中。这也许不是最好的,但是或许必须得这么做。常常会有一些和硬件或者操作系统的细节有关的原因,迫使我们把不愿意耦合在一起的东西耦合在了一起。然而,对于应用的其余部分来说,通过分离它们的接口我们已经解耦了。

六、持久化

  下图展示了一种常见的违反SRP的情形。

  

  Employee类包含了业务规则和对于持久化的控制。这个两个职责在大多数情况下绝不应该混合在一起。业务规则往往会频繁地变化,而持久化的方式却不会如此频繁的变化,并且变化的原因也是完全不同的,它们实在两个方向上变化,一个是业务方向上变化,另一个是持久化方向上变化。

  把业务规则和持久化子系统绑定在一起的做法是自讨苦吃。 测试驱动的开发实践常常会远在设计出现臭味之前就迫使我们分离这两个职责。然而,如果测试没有迫使这种分离,那么就应该使用Facade(外观)、DAO(数据访问)或者Proxy(代理)模式对设计进行重构,分离这两个职责。

七、结论

  SRP是所有原则中最简单的原则之一,也是最难正确运用的原则之一。我们会不自觉地把职责结合到一起。软件设计真正要做的许多工作,就是发现职责并把那些职责相互分离。

SRC单一职责原则的更多相关文章

  1. C#设计模式系列:单一职责原则(Single Responsibility Principle)

    1.单一职责原则的核心思想 一个类应该有且只有一个变化的原因. 2.为什么要引入单一职责原则 单一职责原则将不同的职责分离到单独的类,每一个职责都是一个变化的中心.当需求变化时,这个变化将通过更改职责 ...

  2. C#软件设计——小话设计模式原则之:单一职责原则SRP

    前言:上篇C#软件设计——小话设计模式原则之:依赖倒置原则DIP简单介绍了下依赖倒置的由来以及使用,中间插了两篇WebApi的文章,这篇还是回归正题,继续来写写设计模式另一个重要的原则:单一职责原则. ...

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

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

  4. 开放-封闭原则(OCP)开-闭原则 和 依赖倒转原则,单一职责原则

    单一职责原则 1.单一职责原则(SRP),就一个类而言,应该仅有一个引起它变化的原因 2.如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能会消弱或抑制这个类完成其他职责的能力. ...

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

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

  6. 第2章 面向对象的设计原则(SOLID):1_单一职责原则(SRP)

    1. 单一职责原则(Single Responsibility Principle,SRP) 1.1 单一职责的定义 (1)定义:一个类应该仅有一个引起它变化的原因.这里变化的原因就是所说的“职责”. ...

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

    1.定义 就一个类而言,应该仅有一个引起它变化的原因. 2.定义解读 这是六大原则中最简单的一种,通俗点说,就是不存在多个原因使得一个类发生变化,也就是一个类只负责一种职责的工作. 3.优点 类的复杂 ...

  8. 【设计模式六大原则1】单一职责原则(Single Responsibility Principle)

        http://blog.csdn.net/zhengzhb/article/category/926691/1 图片素材来源,java学习手册 ps.内容为自己整理   定义:不要存在多于一个 ...

  9. [设计模式]<<设计模式之禅>>之关于单一职责原则

    单一职责原则的英文名称是Single Responsibility Principle,简称是SRP. 这个原则存在争议之处在哪里呢?就是对职责的定义,什么是类的职责,以及怎么划分类的职责.我们先举个 ...

随机推荐

  1. js数组转json

    function arrayToJson(o) { var r = []; if (typeof o == "string") return "\"" ...

  2. Google 新推出Background sync API

    Background sync是Google新推出的Web API,可延迟用户行为,直到用户网络连接稳定.这样有助于保证用户想要发送的数据就是实际发送的数据. 目前存在的问题 网络是消磨用户时间最多的 ...

  3. cordova添加platform

    cordova添加platform 一般需要指定版本的 cordova platform add android@4.1

  4. C 中读取键盘码

    键盘码在底层开发中经常用到,有时候我们会忘记它们,就要急急忙忙的去找 键-码 对照表查看,其实程序可以自己打印出 键-码 对应值 #include <stdio.h> #include & ...

  5. struts1的一些基本用法和操作

    入职两周了,项目是用struts1+ibatis框架搭建的,数据库是oracle,其他还行,关键是struts1之前没用用过,所以只好在网上狂查文档,最后大致整理了一些struts1的基本使用方法. ...

  6. agularJs 路由

    angularJs的路由方式: 先定义一个模板ng-app-->然后定义路由的规则(routeProvider)在服务config里-->然后通过不同的URL实现 到单页面加载的所需页面的 ...

  7. 处于同一个域中的两台Sql server 实例无法连接

    处于同一个域中的两台Sql server 实例无法连接,报的错误信息如下: A network-related or instance-specific error occurred while es ...

  8. HTTP与AJAX深入揭秘,不使用AJAX实现页面无刷新

    AJAX的原理是什么? 实际上就是发起HTTP请求,既然就是发起HTTP请求,那只要我们能够实现发起HTTP请求就可以在不使用AJAX的情况下实现相同的效果. 在前端有好多方式可以发起HTTP请求,比 ...

  9. Android 自定义View及其在布局文件中的使用示例(二)

    转载请注明出处 http://www.cnblogs.com/crashmaker/p/3530213.html From crash_coder linguowu linguowu0622@gami ...

  10. Hard Drive Inspector Pro 4.26.208(硬盘检测工具)简体中文特别版

    Hard Drive Inspector监视硬盘错误并且接收警报,检查变化并实施诊断.例如:驱动器旋转时间增加以及数次重试才能运转驱动器通常意味着发动机和/或者轴存在可以导致数据丢失的错误.HardD ...