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

==================================================================

【SRP原则具体解释】

SRP。single responsibility principle。中文翻译为“单一职责原则”!

这是面向对象类设计的第一个原则,也是看起来最简单的一个原则。但这实际上远远没有那么简单,非常多人都不一定真正理解了!

我们随便找几个网上的解释,看看各位大师或者经典站点是怎样解释的:

百度百科(http://baike.baidu.com/view/1545205.htm):

一个类应该有且仅有一个职责。

关于职责的含意。面向对象大师Robert.C.Martin有一个著名的定义:所谓一个类的职责是指引起该类变化的原因,假设一个类具有一个以上的职责,那么就会有多个不同的原因引起该类变化。事实上就是耦合了多个互不相关的职责,就会减少这个类的内聚性。

说句实话,尽管是面向对象大师Martin的解释。我还是看得不甚明确:引起类变化的原因太多了,比如:

给类加一个方法是变化吧?

给类加一个属性是变化吧?

类的函数添加一个參数是变化吧?

。。

。。

引起这些变化的原因太多了,假设每一个原因都是一个职责。那SRP原则简直就没法推断了!

Wiki百科(http://en.wikipedia.org/wiki/Single_responsibility_principle )内容和百度百科基本一致,看起来百度百科像wiki百科的翻译:)

Martin defines a responsibility as a reason to change, and concludes that a class or module should have one, and only one, reason to change.

除了这些标准的解释外,另一种说法:SRP就是指每一个类仅仅做一件事!

这个解释更通俗易懂,也更加适合中国人理解。尽管比Martin大师的解释更清楚一些,但细致想想。还是有个地方比較难以理解:什么叫做“一件事”?

比方说一个学生信息管理类,这个类有“加入学生信息”、“查询学生信息”、“改动学生信息”、“删除学生信息”,那么这是4件事情,还是一件事情呢?

看起来好像是4个事情。但稍有经验的朋友应该都知道,这4个事情绝大部分情况下都是一个类来实现的,而不是分成4个类。

所以关键的问题在于:什么是“一件事”?是每一个功能一件事情么?

事实上答案就在我们自己身上,由于仅仅要我们工作,无时不刻的承担着一定的“职责”。

如今让我们抛开面向对象,抛开软件,抛开计算机。来看看我们自己的“职责”。

比方说。我是一个程序员,我的职责应该是“敲代码”,但敲代码有非常多事情。比如:编码。单元測试、系统測试,bug修复,开会,写文档。。。。

再比方说,我的BOSS是一个管理者,他的职责是“管理程序员”,他也有非常多工作,比如:制定计划,团队建设、开会、协调资源、写文档。。

。。

。。

又比方说。我是一个快递员,也有非常多工作:分包、快递、收款、开会。

。。。

。。

这些职责事实上都不是我们自定义的,而是公司或者部门或者组织给我们安排工作的时候定义的。也就是说:“职责”是站在他人的角度来定义的。而不是自定义的,或许你想把自定义成CEO,但你的老板会真的让你当CEO么?

经过对我们自己的职责的分析,我们能够得出两个关于职责的重要结论:

1) 职责是站在他人的角度来定义的

2) 职责不是一件事。而是非常多事情,但这些事情都是和职责紧密相关的

相应到面向对象设计领域,我们能够说一个类的职责应该例如以下定义:

1) 类的职责是站在其他类的角度来定义的;

2) 类的职责包括多个相关功能;

因此,SRP能够翻译成“一个类仅仅负责一组相关的事情”,相应到代码中就是:一个类有多个方法。这些方法是相关的。

当然,假设你再让我解释什么是“相关”,那我仅仅能吐血了:)

有了这个定义,我们再来看“学生信息管理类”,非常明显,学生管理类具有的4个功能都是和“管理”相关的,依照SRP原则,应该仅仅设计一个“学生信息管理类”就能够了。

【SRP原则范围】

但现实世界往往比理想要复杂,一个最典型的例子就是“办公一体机”。

依据SRP原则,打印机能够设计成一个类。复印机也能够设计成一个类。扫描仪也能够设计成一个类,传真机还是能够设计成一个类。但偏偏就是出了个“办公一体机”。这个机器集成了“打印、复印、扫描、传真”4个职责!

假设我们要设计一个“办公一体机”的类,怎么也不可能设计出一个符合SRP原则的“办公一体机”的类来。

怎么办?是SRP不对么,还是我们永远都不要设计“办公一体机”这种类?

事实上SRP也没有错,“办公一体机”也应该设计。但:不要用SRP来约束“办公一体机”这种类!

也就是说。SRP事实上是有适应范围的,SRP仅仅适合那些基础类,而不适合基于基础类构建复杂的聚合类。

在“办公一体机“的例子中,“打印机”、“复印机”、“扫描仪”、“传真机”都是基础类,每一个类都承担一个职责,而办公一体机是“聚合类”,同一时候集成了4种功能!

细心的朋友可能会继续问道:SRP不能应用于聚合类,那么怎样保证聚合类的设计质量呢?

这个问题的答案在GoF的《设计模式》一书中有具体的答案,即:优先使用对象组合,而不是类继承。具体内容请參考兴许“设计模式”部分的内容

================================================ 
转载请注明出处:http://blog.csdn.net/yunhua_lee/article/details/25279539
================================================

连载:面向对象葵花宝典:思想、技巧与实践(30) - SRP原则的更多相关文章

  1. 连载:面向对象葵花宝典:思想、技巧与实践(28) - 设计原则:内聚&耦合

    前面通过实例解说了一个一环扣一环的面向对象的开发流程:用例模型 -> 领域模型 -> 设计模型(类模型 + 动态模型),解答了面向对象怎样做的问题.接下来我们就要讲"怎样做好面向 ...

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

     ISP,Interface Segregation Principle,中文翻译为"接口隔离原则". 和DIP原则一样,ISP原则也是大名鼎鼎的Martin大师提出来的,他在19 ...

  3. IT第二十天 - 面向对象编程思想、抽象类、异常处理、程序操作日志记录、本周总结 ★★★

    IT第二十天 上午 面向对象编程思想 1.组装电脑的设计: (1)电脑的组成:显示器+机箱 (2)机箱的组成:电源+主板+硬盘 (3)主板所包含的部件:cpu+内存+PCI接口+usb接口 (4)PC ...

  4. python基础----以面向对象的思想编写游戏技能系统

    1. 许多程序员对面向对象的思想都很了解,并且也能说得头头是道,但是在工作运用中却用的并不顺手. 当然,我也是其中之一. 不过最近我听了我们老师的讲课,对于面向对象的思想有了更深的理解,今天决定用一个 ...

  5. 黑马程序员——OC语言基础语法 面向对象的思想

    Java培训.Android培训.iOS培训..Net培训.期待与您交流! (以下内容是对黑马苹果入学视频的个人知识点总结)(一)基础语法 1)关键字 @interface.@implementati ...

  6. Java面向对象的思想

    面向对象的思想 1.面向对象的思想的特点: ①符合人们的日常思考习惯 ②能将复杂的问题简单化 ③将原来的执行者变为了现在的指挥者 面向对象的思想,所谓的对象,其实就是实体.对于实物的描述,通常有两个方 ...

  7. 面向对象编程思想(OOP)

    本文我将从面向对象编程思想是如何解决软件开发中各种疑难问题的角度,来讲述我们面向对象编程思想的理解,梳理面向对象四大基本特性.七大设计原则和23种设计模式之间的关系. 软件开发中疑难问题: 软件复杂庞 ...

  8. U3D 飞机大战(MVC模式)解析--面向对象编程思想

    在自己研究U3D游戏的时候,看过一些人的简单的游戏开发视频,写的不错,只是个人是java web 开发的人,所以结合着MVC思想,对游戏开发进行了一番考虑. 如果能把游戏更加的思想化,分工化,开发便明 ...

  9. OC - 1.面向过程和面向对象的思想对比

    一.面向过程 1> 思想 面向过程是一种以过程为中心的最基础编程思想,不支持面向对象的特性. 面向过程是一种模块化程序设计方法 2> 开发方法 面向过程的开发方法是以过程(也可以说是模块) ...

随机推荐

  1. Dijkstra算法原理及证明(转)

    Dijkstra算法及其证明 算法: 设G是带权图,图中的顶点多于一个,且所有的权都为正数.本算法确定从顶点S到G中其他各个顶点的距离和最短通路.在本算法中P表示带永久标记的顶点的集合.顶点A的前驱是 ...

  2. C Linux read write function extension

    前言 - 赠送 readn / writen Linux 上默认的 read 和 write 函数会被信号软中断. 且 read 和 write 函数中第三个参数 count #include < ...

  3. Linux Shell Scripting Cookbook 读书笔记 3

    patch, tree, head ,tail 1. 创建不可修改文件 chattr +i file chattr -i file 移除不可修改属性 2. 能够启动闪存或硬盘的混合ISO isohyb ...

  4. Codeforces Round #454

    Masha and Bears Tic-Tac-Toe Shockers Seating of Students Party Power Tower Reverses

  5. Android通过百度地图API用Service和Alarm在后台定时获取地理位置信息

    本文主要介绍了Android项目集成百度地图API,使用AlarmManager定时调用Service,在Service中请求坐标更新,并通过坐标得到省.市和县三级地理位置信息的方法. 程序结构很简单 ...

  6. 机器学习PAI为你自动写歌词,妈妈再也不用担心我的freestyle了(提供数据、代码)

    背景 最近互联网上出现一个热词就是“freestyle”,源于一个比拼rap的综艺节目.在节目中需要大量考验选手的freestyle能力,freestyle指的是rapper即兴的根据一段主题讲一串r ...

  7. 4185 Oil Skimming 最大匹配 奇偶建图

    题目大意: 统计相邻(上下左右)的‘#’的对数. 解法: 与题目hdu1507 Uncle Tom's Inherited Land*类似,需要用奇偶建图.就是行+列为奇数的作为X集合,偶尔作为Y集合 ...

  8. 配置DCOM中excel权限

    ASP.NET 导出Excel 错误解决备忘 网站项目要用到导出为excel文件的功能,程序运行时报错:"检索 COM 类工厂中 CLSID 为{000-0000-0000-C0046} 的 ...

  9. 定时器篇---java.util.TimerTask和quartz

    最近项目中出现了定时执行任务的东西,研究了一下,觉得挺不错的,以后还用得到,就总结了下. 这里只介绍两种java.util.Timer 和 quartz java.util.Timer java自带的 ...

  10. vue项目布局

    1.底部有分类布局 类似这种底部有分类的,点击四个tap分别道不同的页面这样的,每个页面都是一个路由,把底部作为一个组件在每一个页面中引入就行.组件就是公用的,能公用的就写成组件.如下 { path: ...