01-单一职责原则(SPR)

1. 背景

    类T负责两个不同的职责:职责P1,职责P2。当由于职责P1需求发生改变而需要修改类T时,有可能会导致原本运行正常的职责P2功能发生故障。

2. 定义

    不要存在多于一个导致类变更的原因。通俗的说,即一个类只负责一项职责。

3. 宏观上

   类层次上存在单一职责原则,同样方法层次上也存在单一职责原则。

4. 补充两个概念

   高内聚:内聚是指类内部的属性和行为,高内聚就是指:一个类的属性和行为与这个类非常密切,称为高内聚。
   低耦合:耦合是指类与类之间或者模块与模块之间的联系,低耦合就是指:耦合度低,易重用、使用灵活。

5. 案例

 需求一:有牛和羊两种动物,它们都需要呼吸空气。

    解决思路:构造动物类,封装呼气空气的方法。

复制代码

 1  public class Animal2     {3         public string myName { get; set; }4 5         private string _name = null;6         public Animal()7         {8 9         }
10         public Animal(string name)
11         {
12             this._name = name;
13         }
14 
15         //封装呼吸空气的方法
16         public void BreathAir()
17         {
19               Console.WriteLine(this._name + "呼吸空气");
21         }
22     }

复制代码

 需求变更:又多了鱼这个物种,它们需要呼吸空气。

   解决方案一:直接在BreathAir上加判断,但是这样违背了方法意义上的单一职责原则

复制代码

 1    public void BreathAir()2         {3             if (this._name.Equals("鱼"))4             {5                  Console.WriteLine(this._name + "呼吸水");   //违背了方法级别的单一职责6             }7             else8             {9                 Console.WriteLine(this._name + "呼吸空气");
10             }
11         }

复制代码

  解决方案二:在Animal类中添加一个BreathWater的方法,但是这样违背了类意义上的单一职责原则

1        //封装呼吸水的方法
2         public void BreathWater()
3         {
4             Console.WriteLine(this._name + "呼吸水");
5         } 

     解决方案三:新建一个WaterAnimal类,在里面封装BreathWater的方法,无论是类级别还是方法级别,都满足了单一职责原则,但是改动成本太大,耗时太长。

复制代码

 1   public class WaterAnimal2     {3          private string _name = null;4          public WaterAnimal(string name)5         {6             this._name = name;7         } 8         //封装呼吸水的方法9         public void BreathWater()
10         {
11             Console.WriteLine(this._name + "呼吸水");
12         }
13     }

复制代码

 综合调用:

复制代码

 1        public static void show()2         {3             //下面模拟单一职责面对需求变更的情况。4             //需求1:有牛和羊两种动物,它们需要呼吸空气5             //解决思路:构造动物类→封装呼吸空气的方法6             Animal animal1 = new Animal("牛");7             Animal animal2 = new Animal("羊");8             animal1.BreathAir();9             animal2.BreathAir();
10 
11             //需求2:又多了鱼这个物种,它们需要呼吸水
12             //解决方案一:在Breath里加判断,但是违背了方法级别的单一职责原则
13             Animal animal3 = new Animal("鱼");
14             animal3.BreathAir();
15 
16             //解决方案二:在Animal类中添加一个BreathWater的方法,但是违背了类级别的单一职责原则
17             Animal animal4 = new Animal("鱼");
18             animal4.BreathWater();
19 
20             //解决方案三:新建一个WaterAnimal类,在里面封装BreathWater的方法,无论是类级别还是方法级别,都满足了单一职责原则,但是改动成本太大,耗时太长
21             WaterAnimal animal5 = new WaterAnimal("鱼");
22             animal5.BreathWater();
23 
24         }

复制代码

  解决方案四:利用委托来解决。

复制代码

 1         /// <summary>2         /// 利用委托的插件式编程3         /// </summary>4         public static void show2()5         {6             Console.WriteLine("------------------下面是利用委托来解决--------------------");7             Animal animal1 = new Animal() { myName = "牛" };8             Animal animal2 = new Animal() { myName = "羊" };9             Animal animal3 = new Animal() { myName = "鱼" };
10             Action<Animal> act1 = Utils.BreathWater;
11             Action<Animal> act2 = Utils.BreathAir;
12             act1.Invoke(animal1);
13             act1.Invoke(animal2);
14             act2.Invoke(animal3);
15         }

复制代码

6. 单一职责原则的好处

 (1). 降低类复杂性,一个类只负责一项职责要比负责多项职责简单的多。

   (2). 提高类的可读性,便于维护。

   (3). 变更引起的风险低,修改一个类的功能,显著降低对其他类的影响。

7. 我的总结

    如果完全遵循单一职责原则,当业务复杂的时候,改动成本是最大的。所以我的原则是:根据实际业务场景,来决定是否违背方法或类层次上的单一职责原则。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/437953.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python3 已经安装相关库,Pycharm 仍然报错 ModuleNotFoundError: No module named 'xxxxxx' 的解决办法

以 requests 库为例&#xff0c;打开 cmd&#xff0c;运行命令 pip install requests&#xff0c;即可安装 requests 库&#xff0c;由于我已经安装过&#xff0c;所以会提示 Requirement already satisfied 此时&#xff0c;我们使用 Pycharm 运行以下代码&#xff1a; impo…

Sharepoint学习笔记—Site Definition系列-- 3、创建ListDefinition

创建一个List Definition有多条途径&#xff0c;这里由于我们要基于前面的用户自定义Content Type来创建一个List Defintion&#xff0c;所以我们就需要使用到List Definition From Content Type模板。 这里先大致描述如何创建List Definition&#xff0c;然后重点介绍一下Li…

Sharepoint学习笔记—error处理-- The user does not exist or is not unique.

看到网上不少人遇到过这种类似的错误&#xff0c;而产生这种错误的原因也有多种&#xff0c;我产生此错误的背景是在试图通过ECMAscript对象模型把一个User添加到某个指定的Group中时遇到的。 问题1.当我试图把一个User添加到Sharepoint的某个指定的Group&#xff0c;…

Knockout学习笔记之二($root,$parent及$data的区别)

以下是我从Google上找到的一个例子&#xff0c;非常生动形象&#xff0c;我修改了部分代码&#xff0c;具体内容如下&#xff1a; 对于$root 与$parent的区别&#xff1a; $root refers to the view model applied to the DOM with ko.applyBindings;译&#xff1a;$root 是指…

GitHub 学生认证,申请 GitHub 学生包

GitHub 面对学生推出了学生认证服务&#xff0c;通过认证后就可以得到学生包&#xff0c;学生包大概有十几项优惠&#xff0c;包括 DATADOG Pro 帐户、免费两年的10台服务器&#xff0c;Icons8 3个月的带图标&#xff0c;照片&#xff0c;插图和音乐订阅服务、JETBRAINS 专业桌…

Python3 使用 pymysql 连接 MySQL 建表时出现 Warning3719 UTF8 警告

在学习 Python3 爬虫关系型数据库储存时&#xff0c;利用 pymysql 连接 MySQL 建表&#xff0c;测试用的代码如下&#xff0c;第一句 SQL 用于获取当前 MySQL 的版本信息&#xff0c;第二句 SQL 执行创建 spiders 数据库的操作&#xff0c;如果程序代码正确&#xff0c;将会输出…

完美解决 bash: hexo: command not found

背景介绍&#xff1a;有好几天没动过 Hexo 博客了&#xff0c;今天准备更新的时候输入 hexo s&#xff0c;报错 bash: hexo: command not found&#xff0c;这是啥情况&#xff1f;以前都好好的&#xff0c;想了一下&#xff0c;大概是这几天折腾各种 Python 库的原因&#xff…

Sharepoin学习笔记 —架构系列--02 Sharepoint的处理(Process)与执行模型(Trust Model) 1

Sharepoint210有四种执行模型: 1、完全信任执行模型(Full Trust) 2、Bin/CAS 执行模型 &#xff08;1与2都属于场解决方案&#xff09; 3、沙盒执行模型(Sand Box) 4、 混合执行方法&#xff08;Hybrid Approach&#xff09; Sharepoint最简单的处理模型就是一个完整的Asp.net应…

Python3 爬虫学习笔记 C10【数据储存系列 — MySQL】

Python3 爬虫学习笔记第十章 —— 【数据储存系列 — MySQL】文章目录【10.1】MySQL 基本操作语句数据库操作表操作表的结构表的数据【10.2】Python 连接 MySQL【10.3】创建表【10.4】插入数据【10.5】更新数据【10.6】删除数据【10.7】查询数据【10.8】实战训练 — 爬取CSDN博…

Sharepoin学习笔记—架构系列--03 Sharepoint的处理(Process)与执行模型(Trust Model) 2

上文我们了解了一个外部Http Request进入IIS 工作进程(W3WP)的处理与执行信任模型&#xff0c;这个阶段是Sharepoint的四种执行模型都必须经过的处理阶段&#xff0c;其中Sharepoint场解决方案与任何 ASP.NET 应用程序一样就是在 IIS 工作进程(w3wp)中运行的&#xff0c;所以上…

Python3 爬虫学习笔记 C11【数据储存系列 — MongoDB】

Python3 爬虫学习笔记第十一章 —— 【数据储存系列 — MongoDB】文章目录【11.1】关于 MongoDB【11.2】MongoDB 基本操作语句【11.3】连接 MongoDB【11.4】指定数据库【11.5】指定集合【11.6】插入数据【11.6】数据查询【11.7】数据计数【11.8】数据排序【11.9】数据偏移【11.…

Sharepoin学习笔记—架构系列--04 Sharepoint的四种执行模型 1

Sharepoint210有四种执行模型 1、完全信任执行模型(Full Trust) 2、Bin/CAS 执行模型 &#xff08;1与2都属于场解决方案&#xff09; 3、沙盒执行模型(Sand Box) 4、 混合执行方法 (Hybrid Approach) 下面分别来看看它们是怎么回事 一、场解决方案 场解决方案是在 Share…

Python3 爬虫学习笔记 C12【验证码对抗系列 — 图形验证码】

Python3 爬虫学习笔记第十二章 —— 【验证码对抗系列 — 图形验证码】文章目录【12.1】关于普通图形验证码【12.2】tesserocr 库识别验证码【12.3】pytesseract 库识别验证码【12.4】验证码处理【12.5】tesserocr 与 pytesserocr 相关资料【12.1】关于普通图形验证码 普通图形…

Sharepoin学习笔记—架构系列--05 Sharepoint的四种执行模型 2

上一篇我们看了场解决方案与沙盒方案两种执行模型&#xff0c;其中场解决方案包括有完全信任方式与Bin/CAS方式两种&#xff0c;这里让我们继续来看看最后一个执行模型&#xff0c;即混合模型(或混合模式)。 三、混合模式&#xff08;hybrid approaches&#xff09; 所谓混合模…

Python3 爬虫学习笔记 C13【验证码对抗系列 — 滑动验证码】

Python3 爬虫学习笔记第十三章 —— 【验证码对抗系列 — 滑动验证码】文章目录【13.1】关于滑动验证码【13.2】滑动验证码攻克思路【13.3】模拟登录 bilibili — 总体思路【13.4】主函数【13.5】初始化函数【13.6】登录函数【13.7】验证码元素查找函数【13.8】元素可见性设置函…

Sharepoin学习笔记—架构系列—06 Sharepoint服务(Services)与服务应用程序框架(Service Application Framework) 1

Sharepoint服务是Sharepoint的重要组成&#xff0c;可以说Sharepoint的许多网站功能都是基于这些服务构架起来的。这里把Sharepoint服务的相关要点总结一下。 1、什么是 SharePoint 服务&#xff1f; SharePoint 服务是一项 IT 服务&#xff0c;它是运行在后台&#xff0c;为调…

Python3 爬虫学习笔记 C14【验证码对抗系列 — 点触验证码】

Python3 爬虫学习笔记第十四章 —— 【验证码对抗系列 — 点触验证码】文章目录【14.1】关于点触验证码【14.2】点触验证码攻克思路【14.3】模拟登录 12306 — 总体思路【14.4】主函数【14.5】初始化函数【14.6】破解入口函数【14.7】账号密码输入函数【14.8】页面截图函数【14…

Sharepoin学习笔记—架构系列—07nSharepoint服务(Services)与服务应用程序框架(Service Application Framework) 2

上一篇我们以问答的方式明确了Sharepoint服务的一些概念&#xff0c;这里我们重点来看两个方面:Sharepoint服务器构架对象模型以及Sharepoint 服务应用程序的某些拓扑结构 一、Sharepoint服务器构架对象模型 转存失败重新上传取消 二、Sharepoint 服务应用程序的某些拓扑结…

Sharepoin学习笔记—架构系列--08 Sharepoint的数据模型(DataModel)、数据管理(Data Management)与查询(Query System)

Sharepoint Foundation中的首要数据结构就是列表(List), 每个List属于某种List Type&#xff0c;与此类似&#xff0c;每个列表中的列(Column)属于某种FieldType&#xff0c;而每一条列表记录(List Item)属于某种Content Type.至于外部数据(External Data)&#xff0c;即来自于…

执行 redis-dump 报错:ERROR (Errno::ENOENT): No such file or directory - ps -o rss= -p xxxxx

redis-dump 命令用于 Redis 数据的导出&#xff0c;执行该命令时报错如下&#xff1a; C:\Users\Lenovo>redis-dump -u 127.0.0.1:6379 ERROR (Errno::ENOENT): No such file or directory - ps -o rss -p 3944解决方法&#xff1a;找到 Ruby 安装目录下的 dump.rb 文件&a…