单一职责原则

SRP(The Single Responsibility Principle):一个类应该只有一个发生变化的原因。这里的变化指职责的变化。

SRP 很好理解,它的要求是 让一个类只做一种类型责任,当这个类需要承当其他类型的责任的时候,就需要分解这个类。听起来很简单,即一个类指做一种事情。这里是一种并不是一件事情。

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

打个比方:生产线上的员工在作业时,他们每个人的工作职责都非常明确,只负责某一个环节,只被安排做某一件事情。这个和 SRP 感觉很像。

如何定义职责

SPR 中,我们把职责定义为变化的原因。如果我们能想到对于一个的动机去改变一个类,那么这个类就具有对于一个的职责。不过,通常情况下,我们会更习惯于用组的形式去考虑职责。

若下面的所示的关系型 Database 处理接口:

public interface IRdbmsStorage
{
  IDbConnection Connection(string connectionString);   IEnumrable<T> Query<T>(string sqlQuery, object param);   T FirstOrDefault<T>(string sqlQuery, object param);   int Count(string sqlQuery, object param);   void Execute(string sqlCommand, object param);   void ExecuteScalar(string sqlCommand, object param);
}

这个接口中我们看到有数据库的连接、数据的查询 和 数据的处理 三个职责。

这三个职责我们需要分开吗?这依赖于应用程序的变化方式。若果说应用程序的变化会影响到连接函数的签名(可能是连接字符串,也可能是 config 中的连接字符串名称),那么这个设计可能存在不合理。也可能代码中某些地方只需要开放查询功能。

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

分离耦合职责

如何分离耦合的职责呢?我们可以分离它们的接口来进行解耦。将多功能的大接口分解成多个单功能的小接口。

public interface IRdbmsStorageQuery
{
  IEnumrable<T> Query<T>(string sqlQuery, object param);   T FirstOrDefault<T>(string sqlQuery, object param);   int Count(string sqlQuery, object param);
} public interface IRdbmsStorageCommand
{
  void Execute(string sqlCommand, object param);   void ExecuteScalar(string sqlCommand, object param);
} public interface IRdbmsStorage : IRdbmsStorageQuery, IRdbmsStorageCommand
{
  IDbConnection Connection(string connectionString);
}

上述代码中我们换分成了 IRdbmsStorageQuery 查询接口 和 IRdbmsStorageCommand 命令 接口(有点 CQS 的味道),然后通过 IRdbmsStorage 接口组合起来。在有些地方我们可能只需要查询功能,有些地方可能用到执行功能,而有些地方可能两者都需要用到。

总结

SPR 原则可以说是面向对象原则中最简单的原则之一,但是也是最难把握的原则之一。软件设计真正要做的许多工作,就是要发现职责并把那些职责相互分离开来。这些职责什么时候该划分职责,划分的颗粒度又有多大,都需要我们去体会。

OOD/DDP 中的 SRP 原则的更多相关文章

  1. TypeScript 中的 SOLID 原则

    下面的文章解释了正确使用 TypeScrip的 SOLID原则. 原文地址:https://samueleresca.net/2016/08/solid-principles-using-typesc ...

  2. 连载:面向对象葵花宝典:思想、技巧与实践(30) - SRP原则

    前面具体阐述了"高内聚低耦合"的整体设计原则.但怎样让设计满足这个原则,并非一件简单的事情.幸好各位前辈和大牛已经帮我们归纳总结出来了,这就是"设计原则"和&q ...

  3. 设计原则:单一职责(SRP)原则

    1 什么是单一职责(SRP)原则 单一职责原则的英文是 Single Responsibility Principle,缩写为 SRP.翻译过来就是:一个类或者模块只负责完成一个职责(或者功能). 所 ...

  4. ASP.NET 设计模式中依赖倒置原则

    依赖倒置原则 A.高层次的模块不应该依赖于低层次的模块,他们都应该依赖于抽象. B.抽象不应该依赖于具体,具体应该依赖于抽象. 依赖倒置原则 A.高层次的模块不应该依赖于低层次的模块,他们都应该依赖于 ...

  5. PCB设计中的20H原则

    20H原则是指电源层相对地层内缩20H的距离,当然也是为抑制边缘辐射效应.在板的边缘会向外辐射电磁干扰.将电源层内缩,使得电场只在接地层的范围内传导.有效的提高了EMC.若内缩20H则可以将70%的电 ...

  6. python中的继承原则

     继承是面向对象的重要特征之一,继承是两个类或者多个类之间的父子关系,子进程继承了父进程的所有公有实例变量和方法.继承实现了代码的重用.重用已经存在的数据和行为,减少代码的重新编写,python在类名 ...

  7. Numpy中的广播原则(机制)

    为了了解这个原则,首先我们来看一组例子: # 数组直接对一个数进行加减乘除,产生的结果是数组中的每个元素都会加减乘除这个数. In [12]: import numpy as np In [13]: ...

  8. JMM中的Happens-Before原则

      在java内存模型中,happens-before应该理解为:前一个操作的结果,可以被后续的操作获取,即内存可见性.   为了解决多线程的内存可见性问题,就提出了happens-before原则, ...

  9. 微服务中的CAP原则

    CAP原则:指的是在一个分布式系统中,Consistency(一致性). Availability(可用性).Partition tolerance(分区容错性),三个要素最多同时实现两点不可能同时实 ...

随机推荐

  1. Jquery调用从ashx文件返回的jsonp格式的数据处理实例

    开发环境:vs2010+jquery-1.4.min.js 解决问题:网上代码比较少,好多调试不通,返回数据不用json而用jsonp主要考虑解决跨域问题 开发步骤:打开VS2010,新建一web站点 ...

  2. VOL.1 利用vmware ThinApp 制作非XP下可以运行的IE6 【无插件版】(windows vista/7/8 x86/x64 )

    作为一名前端开发工程师,不免要考虑IE6的兼容性,但是大部分挑剔的同行们估计都不会用XP,所以基本上IE6的兼容性测试,都是使用IE Tester或者虚拟机. IE Tester的话,很多地方模拟的还 ...

  3. C语言基础知识小总结(2)

    上个总结比较笼统,下面写的稍微详细点吧算是.   一.控制台屏幕打印 1.putchar();   格式: void putchar(char c);  //直接把一个字符输出到屏幕上 2.print ...

  4. jquery 提示信息显示后自动消失的具体实现

    方法一: 复制代码 代码如下: $("#errormsg").html("您的信息输入错误,请重试!").show(300).delay(3000).hide( ...

  5. 关于 复制文本 然后Ctrl+V 操作的这个功能 貌似jq也没有封装。。。

    /* * copy */ function copy(){ var maintext=$("#myhtml").val(); alert(maintext); copyToClip ...

  6. C# 反射之属性操作

    一.反射-类操作 //1.获取对象所有的属性名 Student stu = new Student(); //获取当前类名称 Console.WriteLine(stu.GetType().Name) ...

  7. 数组转换成json

    下面是详细的步骤,也可参考http://blog.csdn.net/wangliqiang1014/article/details/19924727 iOS数组可以转换车json对象,转换代码:NSS ...

  8. 一看就懂ReactJS

    现在最热门的前端框架有AngularJS.React.Bootstrap等.自从接触了ReactJS,ReactJs的虚拟DOM(Virtual DOM)和组件化的开发深深的吸引了我,下面来跟我一起领 ...

  9. Winfroms---看看吧客官~

    假 如 你 的 人 生 有 理 想,那 么 就 一 定 要 去 追,不 管 你 现 在 的 理 想 在 别 人 看 来是 多 么 的 可 笑 , 你 也 不 用 在 乎 , 人 生 蹉 跎 几 十 年 ...

  10. 由C到C++的学习 ----Essential C++

    一.array[] 与 vector<int> vector1 1 array[] <- 此中要填写数组的大小,而且array[]自己是不知道自己的大小的 2.1 vector< ...