单一职责原则

单一职责原则(Single Responsibility Principle)–SRP:

There should never be more than one reason for a class to change.

应该有且仅有一个原因引起类的变更。

单一职责原则好处

  • 降低类的复杂性

每个类实现单一职责,并且单一职责都有清楚明确的定义,复杂性当然降低。

  • 提高可读性
    类的复杂性降低了,当然提高了可读性了。

  • 提高可维护性
    类的复杂性降低,可读性好,当然好维护。

  • 提高扩展性

变更引起的风险降低,变更是必不可少的,如果接口的单一职责做的好,一个接口修改只对相应的实现类有影响,对其它的接口没有影响,这对系统的扩展性,维护性都是有好处的。

类的单一职责原则

一般一个对象可以分为属性行为二部分,所以在类的设计时,我们一般把对象的属性抽象成一个BO(Business Object,业务对象),把对象的行为抽象成一个Biz(Business Logic,业务逻辑)

我们经常会管理一个系统的用户信息,比如修改一个用户的信息(id,密码,名字),添加一个用户信息,删除一个用户信息,对用户进行处理,对用户添加组织和角色。下面有一个类图,就是实现此功能的:

我们假设:
如果一个用户的属性发生改变(id,密码,名字),或者添加,删除用户都会导致类的改变,也就是说此类没有把用户的属性和用户的行为分开,导致了在有用户的属性和用户的行为变化时,UserInfo类也会改变。这就违反了我们的单一职责原则(应该有且仅有一个原因引起类的变更)。

我们按照把用户信息重新抽象成二个接口,一个IUserBO接口负责处理用户的属性,一个IUserBiz接口负责处理用户的行为,这样用户属性改变,只会导致IUserBO接口改变,用户的行为改变,只会导致IUserBiz接口改变,这样也就更符合单一职责原则。

修改后的类图如下:

我们经常使用的代码示例:

.....
IUserInfo userInfo = new UserInfo();//userInfo当作IUserBO来使用
IUserBO userBO = (IUserBO)userInfo;
userBO.setPassword("test");//userInfo当作IUserBiz 来使用
IUserBiz userBiz = (IUserBiz)userInfo;
userBiz.deleteUser();
.....

在实际项目中,我们经常使用这个符合单一职责原则的类图:

接口的单一职责原则

先看几个android开发中我们经常使用的接口:

  • View的click监听接口OnClickListener:

在frameworks/base/core/java/android/view/View.java代码中,接口OnClickListener定义

    /*** Interface definition for a callback to be invoked when a view is clicked.*///View的click监听接口public interface OnClickListener {void onClick(View v);}
  • View的长按监听接口OnLongClickListener

在frameworks/base/core/java/android/view/View.java代码中,接口OnLongClickListener 定义:

    /*** Interface definition for a callback to be invoked when a view has been clicked and held.*///View的长按监听接口public interface OnLongClickListener {boolean onLongClick(View v);}
  • SeekBar控件的改变监听接口

在frameworks/base/core/java/android/widget/SeekBar.java代码中,接口OnSeekBarChangeListener 定义:

//SeekBar控件的改变监听接口
public interface OnSeekBarChangeListener {//进度改变监听void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser);//开始拖动进度条时监听void onStartTrackingTouch(SeekBar seekBar);//拖动进度条结束时监听void onStopTrackingTouch(SeekBar seekBar);
}

从上面的三个例子,我们可以清楚的看到OnClickListener接口只针对点击功能定义onClick方法,OnLongClickListener接口只针对长按功能定义onLongClick方法,OnSeekBarChangeListener 接口针对SeekBar控件进度条改变功能定义了一组相关的三个方法。

可见,优秀接口的定义都是符合单一职责原则,针对单一的职责定义单一的方法或是相关的一组方法。

#方法的单一职责原则
其实类也好,接口也好,最后归根到底还是要方法来支持和实现,所以方法的单一职责是非常关键重要的。

方法的单一职责原则简单来说就是一个方法实现一个功能,解决一个方法。

符合单一职责原则的方法,会更方便系统的调用,但是如果方法过细的拆分,也会导致方法的剧增和类或接口的复杂,因此在具体项目中还是把握一个度。

下面一个修改用户信息的样例:
一个是一个方法不符合单一职责原则,changerUser方法承担多个职责,必然导致此方法复杂,产适合其它方法来复用。

一个是每个方法都符合单一职责原则,changeUserName实现修改名字,changeHomeAddress实现修改家庭地址,changeTele实现修改电话,每个方法都职责明确清楚,逻辑也清晰明了,非常适合其它方法来调用。

总结

对于单一职责原则,我们的建议是接口一定要做到单一职责原则,类的设计尽量做到只有一个原因引起变化。

参考资料

设计模式之禅 秦小波著 机械工业出版社

六大设计原则之单一职责原则相关推荐

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  8. 六大设计原则之单一职责原则(SRG)

    在做代码练习或者开发的过程中,我们会发现自己写的类越来越大,该类的功能也越来越多.有一些开发者包括之前的我看到自己写的类够大,功能够多是往往会充满自豪感.但是当某个功能需要做一个小改动时,就会发现整个 ...

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

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

最新文章

  1. Apache+tomcat+mysql安装步骤
  2. tableau实战系列(二十八)-以可视化的方式打开关联分析算法购物篮分析(Market Basket Analysis)
  3. 使用Visual Studio 2019开发Qt程序
  4. 交换机工作原理及实验浅析
  5. Java中反射机制(Reflection)学习
  6. 如何在本地数据中心安装Service Fabric for Windows集群
  7. 多表操作查询 一对一
  8. Hibernate的fetch
  9. HTML和css学术报告,清华大学 张超 副教授访问我院并做学术报告
  10. 局域网服务器没显示,无法登录服务器 局域网也不显示连接
  11. JavaScript之array
  12. FFmpeg示例程序合集-Git批量获取脚本
  13. 在iOS开发中,我们会遇到十六进制和字符串之间相互转换,话不多说,直接上代码:...
  14. codeforces 212E IT Restaurants(树形dp+背包思想)
  15. php把日期转成时间戳,php如何把日期转为时间戳
  16. 香橙派进入系统后设置ip
  17. 数构与算法 | 什么是大 O 表示算法时间复杂度
  18. AutoLeaders控制组——51单片机学习笔记(AD/DA、红外遥控)
  19. 【电脑办公软件】万彩办公大师教程丨TextDiff文本比较工具
  20. omi html转义,特殊字符读法

热门文章

  1. css适配iPhoneX,iPhone XS Max,iPhoneXR,
  2. 南京 超级计算机,这周武汉南京合肥杭州都要下雪?超级计算机:还有变数
  3. 15. 存储引擎和表类型
  4. MES系统下设备管理系统操作简单,功能强大,欢迎了解使用
  5. 荣耀智慧屏和TCL智屏接踵而至,客厅娱乐又要变天了?
  6. Python中拼音库PyPinyin的使用
  7. 英语六级作文万能句型总结
  8. 鹅厂如何构建大型基础网络平台
  9. 【java基础知识】日期类
  10. java test60006_派派6.0006旧版本v60006 老版本 Android