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

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

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

【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
================================================

时间: 2024-11-10 18:53:29

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

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

 ISP,Interface Segregation Principle,中文翻译为"接口隔离原则". 和DIP原则一样,ISP原则也是大名鼎鼎的Martin大师提出来的,他在1996年的C++ Reporter发表" The Interface Segregation Principle"的文章详细阐述了ISP原则,并且在他的经典著作< Agile Software Development, Principles, Patterns>(中文翻译为:敏捷

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

DIP,dependency inversion principle,中文翻译为"依赖倒置原则". DIP是大名鼎鼎的Martin大师提出来的,他在1996 5月的C++ Reporter发表" The Dependency Inversion Principle"的文章详细阐述了DIP原则,并且在他的经典著作< Agile Software Development, Principles, Patterns>(中文翻译为:敏捷软件开发:原则.模式与实践

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

LSP是唯一一个以人名命名的设计原则,并且作者还是一个"女博士"  ============================================================= LSP,Liskov substitution principle,中文翻译为"里氏替换原则". 这是面向对象原则中唯一一个以人名命名的原则,尽管Liskov在中国的知名度没有UNIX的几位巨匠(Kenneth Thompson.Dennis Ritchie).GOF四人帮那么

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

开闭原则是一个大部分人都知道,但大部分人都不懂的设计原则! ==================================================================== OCP,Open-Closed Principle,中文翻译为"开闭原则". 当我第一次看到OCP原则时,我的感觉就是这原则也太抽象了吧,什么开,什么闭呢? 然后我去寻找更加详细的答案,最经典也是最常见的解释就是维基百科了: http://en.wikipedia.org/wiki/Open

连载:面向对象葵花宝典:思想、技巧与实践(36) - 设计原则如何用?

经过前面深入的阐述,SOLID的原则我们已经基本上讲清楚了,但如果想熟练的应用SOLID原则,仅仅知道SOLID是什么(what)还不够,我们还需要知道SOLID原则在什么时候和什么场景应用(when或where). 幸运的是,SOLID原则的5个独立原则在实际应用中基本上都是独挡一面,并不会在某个地方需要同时从可选的几个原则中挑选一个最优的原则来应用,这样大大降低了我们应用SOLID原则的难度. SOLID原则具体的应用场景如下: SRP原则:用于类的设计 当我们想出一个类,或者设计出一个类的

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

NOP,No Overdesign Priciple,不要过度设计原则. 这应该是你第一次看到这个原则,而且你也不用上网查了,因为这个不是大师们创造的,而是我创造的:) 之所以提出这个原则,是我自己吃过苦头,也在工作中见很多人吃过类似的苦头. 你可能也见过这样的场景: 产品提出了一个需求,设计师眼光非常长远,他甚至把5年后可能的业务变化都提出来并且加以设计了,让你不得不佩服设计师的高瞻远瞩的眼光,并且由衷的从心底赞叹:牛逼啊! 但很快你就会发现,设计师是很牛逼,但你开发的时候就很苦逼了,设计方案

连载:面向对象葵花宝典:思想、技巧与实践(37) - 设计模式:瑞士军刀 or 锤子?

"设计模式"这个词几乎成为了软件设计的代名词,很多人非常天真的以为掌握了设计模式就掌握了软件设计,但实际上如果只是握了设计模式,软件设计的门都还没摸到! ======================================================== 谈起设计模式,那是几乎无人不知,无人不晓,大名鼎鼎的"GOF"(中文有的翻译为"四人帮")惊世之作,真是"平生不识GOF,学尽设计也枉然!" 然而,设计模式真的是

连载:面向对象葵花宝典:思想、技巧与实践(39) - 设计原则 vs 设计模式

又是设计原则,又是设计模式,到底该用哪个呢? ============================================================================= 在"设计模型"一章中,我们提到设计原则和设计模式是互补的,设计原则和设计模式互补体现在:设计原则主要用于指导"类的定义"的设计,而设计模式主要用于指导"类的行为"的设计. 举一个很简单的例子:假设我们要设计一个图形类Shape,这个类既支持三角形,

连载:面向对象葵花宝典:思想、技巧与实践(29) - 高内聚低耦合

高内聚低耦合,可以说是每个程序猿,甚至是编过程序,或者仅仅只是在大学里面学过计算机,都知道的一个简单的设计原则. 虽然如此流行和人所众知,但其实真正理解的人并不多,很多时候都是人云亦云. =============================================================== 要想真正理解"高内聚低耦合",需要回答两个问题: 1)为什么要高内聚低耦合? 2)高内聚低耦合是否意味内聚越高越好,耦合越低越好? 第一个问题:为什么要高内聚低耦合? 经典的