OOD/DDP 中的 SRP 原则

单一职责原则

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

时间: 2024-10-05 05:32:21

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

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

依赖倒置原则 A.高层次的模块不应该依赖于低层次的模块,他们都应该依赖于抽象. B.抽象不应该依赖于具体,具体应该依赖于抽象. 依赖倒置原则 A.高层次的模块不应该依赖于低层次的模块,他们都应该依赖于抽象. B.抽象不应该依赖于具体,具体应该依赖于抽象. 目录 1概述 2意图 3代码实现 4结构图 1概述编辑 所谓依赖倒置原则(Dependence Inversion Principle)就是要依赖于抽象,不要依赖于具体.简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现

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

前面具体阐述了"高内聚低耦合"的整体设计原则.但怎样让设计满足这个原则,并非一件简单的事情.幸好各位前辈和大牛已经帮我们归纳总结出来了,这就是"设计原则"和"设计模式".毫不夸张的说,仅仅要你吃透这些原则和模式并熟练应用,就能够做出非常好的设计. ================================================================== [SRP原则具体解释] SRP.single responsibil

Hbase中rowkey设计原则

Hbase中rowkey设计原则 1.热点问题 在某一时间段,有大量的数据同时对一个region进行操作 2.原因 对rowkey的设计不合理 对rowkey的划分不合理 3.解决方式 rowkey是hbase的读写唯一标识 最大长度是64KB. 4.核心原则 设计必须按照业务需求进行设计 5.长度原则 经验:10~100字节可以 官方:16字节,因为操作系统时8字节进行存储 6.散列原则 划分region是按照rowkey的头部进行划分. 有几种方式: )组合字段 id+timestamp )

3.6 盒子在标准流中的定位原则

如果要精确地控制盒子的位置,就必须对margin有更深入的了解.padding只存在于一个盒子内部.所以通常它不会涉及与其他盒子之间的关系和相互影响的问题.margin则用于调整不同的盒子之间的位置关系,因此必须要对margin在不同情况下的性质有非常深入的了解. 一.实验1——行内元素之间的水平margin 这里来看两个块并排的情况,如图1所示. 图1 行内元素之间的margin 当两个行内元素紧邻时,它们之间的距离为第1个元素的margin-right加上第2个元素的margin-left,

编程中的正交原则

今天读到了<程序猿的修炼之道>关于"正交的优点"一节,突然间想起了一件事情. 关于当年參加飞思比赛的故事. 话说參加完这个比赛之后,最引以为豪的作品还是由我们队一路摸索建立起来的无线通信上位机调试技术(就姑且称之为技术吧),这项技术带来的优点是显而易见的,方便的查看各项执行数据为调整策略提供根据,方便的设置关键变量以尽快获取最佳执行參数.方便的检查各类传感器状态以确定其执行是否正常. 因此,我多次建议后来的师弟将这一成果沿用下去.并进行必要的改进. 在为他们提供的技术资料中

02 java中的solid原则

问题 java中的solid原则是什么 答案 Single Responsibility Principle:单一职责原则 一个方法只做一件事情只有一个职责,一个类只做一组相关的事情.承担相近的职责.如果方法做了多个事情,当别人想使用这个方法中的第一个事情时,其他事情也不得不发生,如此一来就得拆分这个方法.如果这个方法在定义的时候就做一件事情,那么就不会被拆分,维护起来也方便好多,对于类也有这种约束.这就是单一职责原则.请看下面的代码: //下面这个方法就不符合单一职责原则,因为调用者只想使用该

OO设计中5大原则

1.SRP(Single Responsibility Principle) 单一职责原则 单一职责原则就是一个设计元素只做一件事 2.OCP(Open Close Principle) 开闭原则 Open for extension , Close for Modification ,对修改关闭,对扩展开放,便于重用 3.LSP(Liskov Substitution Principle) 里氏替换原则 同一个继承体系中的对象应该具有共同的行为特征 DBC (Design By Contrac

设计模式-7中常用设计原则简述

7种常用的面向对象设计原则 设计原则名称 定  义 单一职责原则 (Single Responsibility Principle, SRP) 一个类只负责一个功能领域中的相应职责 开闭原则 (Open-Closed Principle, OCP) 软件实体应对扩展开放,而对修改关闭 里氏代换原则 (Liskov Substitution Principle, LSP) 所有引用基类对象的地方能够透明地使用其子类的对象 依赖倒转原则 (Dependence  Inversion Principl

架构中的设计原则

1. 单一职责原则 Single Responsibility Principle 系统中每一个类都应该只有一个单独的职责 2. 里氏替换原则 Liskov Substitution Principle 任何父类出现的地方都可以用它的子类来替代 3. 依赖注入原则 Dependence Inversion Principle 要依赖于抽象,不要依赖于具体的实现 4. 接口分离原则 Interface Segregation Principle 不应该强迫客户程序依赖他们需要使用的方法 5. 迪米