目录

一、简介

二、概念

三、原理

四、示例

五、优化

六、总结


一、简介

在学习设计模式之前,首先需要了解软件设计的七大原则:

  • 单一职责原则
  • 接口隔离原则
  • 依赖倒置原则
  • 里氏替换原则
  • 开闭原则
  • 迪米特原则
  • 合成复用原则

二、概念

对类而言,一个类/接口/方法应该只负责一项职责。

A负责两个不同的职责:职责P1,职责P2。当由于职责P1需求发生改变而需要修改类T时,有可能会导致原本运行正常的职责P2功能发生故障。也就是说职责P1和P2被耦合在了一起。所以需要将类A分解为A1、A2,使A1、A2分别负责职责1、职责2,两者互不影响。

解决方法:遵守单一职责原则,将不同的职责封装到不同的类或模块中,分别建立两个类T1、T2,使T1完成职责P1功能,T2完成职责P2功能。这样,当修改类T1时,不会使职责P2发生故障风险;同理,当修改T2时,也不会使职责P1发生故障风险。

三、原理

如果一个类承担的职责过多,就等于把这些职责耦合在一起,这个类耦合度就比较高,这样某一天其中一个职责的变化可能会影响甚至导致其他职责不可用。如果想要避免这种现象的发生,就要尽可能的遵守单一职责原则。此原则的核心就是解耦和增强内聚性。

四、示例

下面举一个违反单一职责原则的例子:

public class SingleResponsibility {public static void main(String[] args) {Animal animal = new Animal();animal.animal("狗");animal.animal("老虎");animal.animal("牛");animal.animal("羊");}
}class Animal{public void animal(String animal) {System.out.println(animal + "是肉食动物...");}
}

运行结果:

很明显,牛、羊并不是肉食动物,而是植食动物,所以上述的代码有点问题。下面我们修改时如果遵循单一职责原则,需要将Animal类细分为肉食动物和植食动物,代码如下:

public class SingleResponsibility {public static void main(String[] args) {CarnivorousAnimal carnivorousAnimal = new CarnivorousAnimal();carnivorousAnimal.animal("狗");carnivorousAnimal.animal("老虎");HerbivoresAnimal herbivoresAnimal = new HerbivoresAnimal();herbivoresAnimal.animal("牛");herbivoresAnimal.animal("羊");}
}/*** 肉食动物*/
class CarnivorousAnimal{public void animal(String animal) {System.out.println(animal + "是肉食动物...");}
}/*** 植食动物*/
class HerbivoresAnimal{public void animal(String animal) {System.out.println(animal + "是植食动物...");}
}

运行结果:

我们会发现如果这样修改花销是很大的,除了将原来的类分解之外,还需要修改客户端的代码。

五、优化

但是,如上面的修改方式其实修改量有点大,而且扩展性不好,假如哪一天又有新需求,需要将肉食动物再进一步分类等等, 又需要将CarnivorousAnimal类进行分解,这样不太好。

public class SingleResponsibility2 {public static void main(String[] args) {Animal animal = new Animal();animal.carnivorousAnimal("狗");animal.carnivorousAnimal("老虎");animal.herbivoresAnimal("牛");animal.herbivoresAnimal("羊");}
}/*** 由于逻辑足够简单,这里在代码上违反单一职责原则,但是在方法级别上是满足单一职责,每个方法只负责一项职责,* 而且还不需要大量修改客户端代码 * * 当然,肯定会有同学说这里可以使用接口,然后使用多态实现,本文主要展示单一职责原则, 只是为了说明单一职责的问题,所以此处没有使用接口或者抽象类方式。*/
class Animal{public void carnivorousAnimal(String animal) {System.out.println(animal + "是肉食动物...");}public void herbivoresAnimal(String animal) {System.out.println(animal + "是植食动物...");}
}

运行结果:

可以看到,这种修改方式没有改动原来的方法,而是在类中新加了一个方法,这样虽然在代码级别违背了单一职责原则,但在方法级别上却是符合单一职责原则的,因为它并没有修改原来方法的代码。

六、总结

本文只是简单的说明单一职责原则的示例,我们需要在实际项目中好好领会这种思想并且运用到项目中去,这样我们才能真正有效地遵循单一职责原则来达到‘高内聚、低耦合’的目标。以下总结单一职责原则的优缺点:

优点:

  • a. 单一职责原则降低类的复杂度,一个类只负责一项职责;
  • b. 提高类的可读性,可维护性;
  • c. 降低变更引起的风险;
  • d. 通常情况下,应当遵循单一职责原则,只有在类的逻辑足够简单的情况下,可以在代码级别上违反单一职责原则:只有类中的方法足够少,可以在方法级别上保持单一职责原则;

缺点:

  • 如果一味追求这个单一职责,因为要分解类,可能会造成大量多余的类,这样也不好,不过接口和方法应该遵循这个原则;

软件设计原则(一) 单一职责原则相关推荐

  1. Java设计原则之单一职责原则、开闭原则、里氏代换原则

    文章目录 面向对象设计原则概述 单一职责原则 开闭原则 里氏代换原则 面向对象设计原则概述 软件的可维护性(Maintainability)和可复用性(Reusability)是两个非常重要的用于衡量 ...

  2. 设计原则:单一职责原则

    单一职责原则(SRP) 单一职责原则的英文是 Single Responsibility Principle,缩写为 SRP.这个原则的英文描述是这样的:A class or module shoul ...

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

    本文详解设计原则中的单一职责原则,目的还是提高代码的可读性.可扩展性.复用性.可维护性等. 目录 1. 单一职责原则(SRP) 2. 如何理解单一职责原则? 3. 如何判断类的职责是否足够单一? 4. ...

  4. 面向对象的七种原则:单一职责原则,开放关闭原则

    我们的知识星球马上就要开始更新设计模式了,在更新设计模式之前,我们是不是需要做一些准备呢?否则设计模式中一些遵循的原则大家会一头雾水,所以我今天来给大家说一些面向对象的七种原则,有人说是6种有人说是7 ...

  5. SOLID原则:单一职责原则(SRP)

    SOLID:SOLID 原则并非单纯的1个原则,而是由5个设计原则组成,它们分别是:单一职责原则.开闭原则.里式替换原则.接口隔离原则和依赖反转原则,SOLID 由5个设计原则的头一个字母组成. 如何 ...

  6. 设计模式六大原则(一)----单一职责原则

    设计模式六大原则之[单一职则原则] 一.什么是单一职责原则 首先, 我们来看单一职责的定义. 单一职责原则,全称Single Responsibility Principle, 简称SRP. A cl ...

  7. 接口隔离原则和单一职责原则区别

    接口隔离原则和单一职责原则区别 单一职责原则是备受争议的原则,根据不同的业务逻辑,它会将系统功能模块划分成不同种类,产生多样的接口,同时每个接口尽量只包含一个功能(方法). 而产生争议的原因就是这个业 ...

  8. 设计模式---面向对象设计原则之单一职责原则

    单一职责原则是最简单的面向对象设计原则,它用于控制类的粒度大小.单一职责原则定义如下: 单一职责原则(Single Responsibility Principle, SRP):一个类只负责一个功能领 ...

  9. 6大设计原则之单一职责原则

    单一职责原则 如果有一个用户管理类,类图如下 我想,任谁也能看的出这个接口设计的有问题,用户的属性和用户的行为没有分开,应该把用户的信息抽取成一个业务对象,把用户的行为抽取成一个业务对象,按照这个思路 ...

  10. 架构中的设计原则之单一职责原则 - 《java开发技术-在架构中体验设计模式和算法之美》...

    2019独角兽企业重金招聘Python工程师标准>>> 单一职责模式: 单一职责原则的核心思想就是:系统中的每一个对象都应该只有一个单独的职责,而所有对象所关注的就是自身职责的完成. ...

最新文章

  1. 基于Directshow框架使用Windows渲染器VMR叠加水印
  2. mediawiki java_使用MediaWiki 1.16.0实现添加媒体向导
  3. 膜拜大丹(结论+二元环)
  4. Max retries exceeded with url 解决方案
  5. 操作系统02进程管理Process_Description_and_Control
  6. mysql raid_DBA们应该知道的RAID卡知识_MySQL
  7. 创建对象的内存理解(图示)
  8. vb杨辉三角代码编写_杨辉三角怎样用VB写杨辉三角的完整代码 – 手机爱问
  9. ES6 走马观花(ECMAScript2015 新特性)
  10. 2019 年各地移动 APT事件总结
  11. 理解VML||MKL
  12. 抢跑俞敏洪,教培人“玩命”直播
  13. Grafana使用双Y坐标轴详解
  14. appleID有必要开双重认证吗!
  15. Android-服务Service(2)-bind绑定Service及两种生命周期
  16. 【pytest】内置 fixtures 之 tmpdir:创建临时文件
  17. android弱网模拟路由器,Mac 下使用命令行模拟弱网环境
  18. 很齐全的怀孕常识 收藏备用
  19. 【日本动漫推荐】十一长假动画推荐情报~
  20. p_conc_request_id

热门文章

  1. java cron 解析_quartz cron 在线解析
  2. 阿里云云计算 52在线实验--云监控初体验
  3. linux中fb0和fb1同时显示数据,Linux frame buffer驱动设计与实现
  4. OLTP在线事务处理
  5. MySQL常用命令介绍
  6. mysql连接操作_MySQL内连接操作
  7. 【Gym-100889 H】Hitting Points【凸包三分】
  8. 机器学习的偏差-方差分解
  9. 使用bbscope进行大规模域名收集扫描
  10. Raki的读paper小记:PURE:A Frustratingly Easy Approach for Entity and Relation Extraction