一个厨子能够做出一手好菜,或许他是新东方毕业的或者是祖传秘方。你让他做上一桌佳肴那是简单、快乐而又高效的,然而让他编程就会成为一种苦恼并且让人想不通的一件事。或许这个比喻不是非常恰当,可是对于每一个类来说,他们就像一个一个的actor,或许是厨子或许是司机,他们应该关注于自己的领域,这样会更加高效并且简明。源于这一思想,我们发现了SRP这个原则,即:单一职责原则。

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

     既然是UML入门,我们也不能跑偏了主题。在讨论SRP原则的同一时候,我们用实例并用UML类图来表示。
     尽管话说的easy,可是实际项目中还是会出现非常多问题,比如怎样进行责任划分(本来就是一个无法量化的概念)。在探讨一个类是否满足SRP原则时,我们能够思考这个类是否仅仅因一个原因而改变,即其他的原因不能导致该类的改动。在j2ee MVC(Model View Controller) 开发模式中我们知道,Model层仅仅负责业务逻辑,View仅仅负责页面的显示而Cotroller仅仅负责数据的传递。除了页面的改变这一个原因以外,其他不论什么的变化都不会引起View层代码的改变,这就是SRP原则。在java的面向对象思想中我们也能够找到SRP原则的影子,比如面向对象的三大特性:继承、封装和多态。以下我们就以实例来讨论怎样在代码层实现SRP原则。

  1.利用接口满足SRP原则


     首先我们定义一个Person类,事实上就是那个厨子。可是上司让他不仅要做饭还要编程,因此,这个类用UML表示为
     
    

     当然如今看起来这个类并非非常复杂,由于它并没有太多方法,我们在这仅仅是演示。首先这个类的定义存在缺陷:我们并非非常清晰的知道这个类的职能是什么,它失去了作为厨子的特性。那么,我们能够通过接口来实现
     
    

     如今我们细致分析Cooker和Coder这两个接口的作用。在Cooker这个接口类中,我们能够定义全部有关厨艺的方法,无论是鲁菜、川菜还是粤菜都在里面。假设这个厨子比較上进,学习了湘菜,我们也仅仅须要在Cooker中加入对应的方法就OK了,并且不会引起Coder类的不论什么变化,体现了封装性。
     只是这个样例也能够这么来表示:
     
    

     在这个样例中貌似这两种做法都可行。我们能够这样思考一下:假设这个厨子是新东方毕业的,每一个从新东方毕业的学习都是大同小异。这样,我们就能够定义一个Cooker接口,仅仅要是实现这个接口的人,就能够看作是新东方毕业的,都会川菜。假设採用另外一种方式的话,那就要定义N个类,然后每一个类中都须要写一个川菜的方法,这样显得多余并且没有效率。并且,万一有一天当中的一个厨子学会了开车,我们仅仅须要再实现Drive接口就OK了,事实上这也是java中继承和接口的差别,1.我们通过接口实际上定义了一个模板,接口中的方法大多数情况下是已知的,因此能够利用反射的方式,动态的对方法进行改动。2.使用接口,我们能够更好的实现多态,能够把接口当作參数传递。3.我们能够实现一般继承不能实现的多继承。详细有关接口的优点,能够參照http://blog.csdn.net/rocketboy911/article/details/1633414中的实际案例。

2.使用继承来实现SRP原则


     在上一部分,我们讨论了继承和接口的差别,在这一部分我们又要来探讨使用继承来实现SRP原则,博主这人还真逗,自相矛盾了。事实上不然,这里的继承是指父子类的继承,而非方法的继承。我们来回想一下刚才的知识,整理一下思路:从新东方毕业的学生都会川菜,那么我们说在这里使用接口而非继承。假设我们把厨子和程序猿放在一起,那么他们都是Person,这里我们要用继承而非接口。
     在这里我们先忘掉那个倒霉的厨子,我们先定义一个Student类,它拥有read(),dance(),sing()三个方法:

    

     但我们发现,尽管每一个同学都会读书,可是并非每一个同学都会跳舞,并且有些还是五音不全。那我们说,这个类还是有问题,我们利用继承对这个类进行改动:

    

     这样我们能够清楚看来:噢!是Lee会唱歌,而David会跳舞,同一时候他们都继承了Student的read()方法,成为了一个多才多艺的学生。并且以后假设要改变sing()的代码的时候,我们不是必需像曾经一样,改动整个Student的代码,我们仅仅须要改动Lee的一部分就OK了。

3.有关SRP持久化


     这个样例来源于UML for java program这本书。并没有太多的理解,先放在这里。

    

     (上图左边单词拼写错误,摘自书中)
     左边说明了Employee和持久化的依存关系,Persistable的改变会或多或少的改变Employee,这是我们不同意的。可是持久化的需求是永远存在的,因此我们能够使用右边的结构,分离开Employee和Persistable的关系,实现SRP原则

UML之轻松入门(3)-SRP做好厨子,让别人编程去吧的更多相关文章

  1. UML之轻松入门(2)-掌握Junit,让我们的开发更高效

         使用UML不仅能够形象化的表达我们的程序思想,并且能够帮助我们提高程序的质量.一个杂乱无章的程序让维护者望而生畏,其成本也可想而知.在面向程序设计(OOD)中有5条原则是帮助我们设计一个高效 ...

  2. Groovy轻松入门——通过与Java的比较,迅速掌握Groovy (更新于2008.10.18)

    摘自: http://www.blogjava.net/BlueSUN/archive/2007/03/10/103014.html Groovy轻松入门--通过与Java的比较,迅速掌握Groovy ...

  3. Groovy轻松入门——搭建Groovy开发环境

    摘自: http://www.blogjava.net/BlueSUN/archive/2007/03/17/104391.html Groovy轻松入门--搭建Groovy开发环境 多日来,我发表了 ...

  4. C++ STL编程轻松入门基础

    C++ STL编程轻松入门基础 1 初识STL:解答一些疑问 1.1 一个最关心的问题:什么是STL 1.2 追根溯源:STL的历史 1.3 千丝万缕的联系 1.4 STL的不同实现版本 2 牛刀小试 ...

  5. Swift轻松入门——基本语法介绍和详细地Demo讲解(利用WebView打开百度、新浪等网页)

    转载请务必注明出处(all copyright reserved by iOSGeek) 本文主要分为两个部分,第一部分介绍Swift的基本语法,第二部分讲解一个利用WebView来打开百度.sina ...

  6. JavaScript面向对象轻松入门之封装(demo by ES5、ES6、TypeScript)

    本章默认大家已经看过作者的前一篇文章 <JavaScript面向对象轻松入门之抽象> 为什么要封装? 封装(Encapsulation)就是把对象的内部属性和方法隐藏起来,外部代码访问该对 ...

  7. asp.net core轻松入门之MVC中Options读取配置文件

    接上一篇中讲到利用Bind方法读取配置文件 ASP.NET Core轻松入门Bind读取配置文件到C#实例 那么在这篇文章中,我将在上一篇文章的基础上,利用Options方法读取配置文件 首先注册MV ...

  8. AngularJs轻松入门

    AngularJs轻松入门系列博文:http://blog.csdn.net/column/details/angular.html AngularJs轻松入门(一)创建第一个应用 AngularJs ...

  9. Groovy轻松入门——通过与Java的比较,迅速掌握Groovy

    转自 :Groovy轻松入门——通过与Java的比较,迅速掌握Groovy (更新于2008.10.18) 在前几篇文章中,我已经向大家介绍了Groovy是什么,学习Groovy的重要性等内容,还不了 ...

随机推荐

  1. linux 终端控制-- 多彩输出 格式排版

    linux 终端控制-- 多彩输出 格式排版 在unix/linux的终端下,怎么控制终端输出的颜色和格式呢,当然了有专门的工具,tput,但是能被terminal直接读懂的格式化字符串更通用. 先来 ...

  2. iPhone开发【一】从HelloWorld開始

    转载请注明出处,原文网址:http://blog.csdn.net/m_changgong/article/details/8013553 作者:张燕广 从经典的HelloWorld開始踏入iPhon ...

  3. Function 详解(一)

    一直想写一系列关于javascript的东西,可惜从申请博客以来就一直抽不出时间来好好写上一番,今天终于熬到周末,是该好好整理一下,那么先从声明函数开始吧; 总所周知,在javascript中有匿名函 ...

  4. TForm.ShowModal只是接管消息循环,禁止外部键盘和鼠标输入到别的窗口,但并不封锁其它窗口继续获取消息(比如WM_TIMER消息仍可被发送到别的窗口上)

    窗体上放一个TTimer,然后双击输入: procedure TForm1.Timer1Timer(Sender: TObject); var cvs: TCanvas; Rect: TRect; S ...

  5. HDU1176:免费馅饼(DP)

    Problem Description 都说天上不会掉馅饼,但有一天gameboy正走在回家的小径上,忽然天上掉下大把大把的馅饼.说来gameboy的人品实在是太好了,这馅饼别处都不掉,就掉落在他身旁 ...

  6. 算法起步之动态规划LCS

    原文:算法起步之动态规划LCS 前一篇文章我们了解了什么是动态规划问题,这里我们再来看动态规划另一个经典问题,最长公共子序列问题(LCS),什么是子序列,我们定义:一个给定序列将其中的0个或者多个元素 ...

  7. eclipse中我要同时看两个console

    eclipse中我要同时看两个console 有一个按钮“New Console View”,可以让你再建一个Console,还有一个按钮“Display Selected Console”,可以在两 ...

  8. 利用Perf4j 对java项目进行性能监控

    Perf4j 可以对自定义监控范围的java代码进行日志记录,再经统计分析生成所需性能数据.Perf4j 提供了对常用日志工具log4j的扩展以方便与产品集成,它产生的性能数据可被用于生成可视化的性能 ...

  9. Git使用之搭建基于SSH的Gitserver(上篇)

    1. 须要软件 msysgit (Gitfor Windows) Copssh (OpenSSHfor Windows,新版本号已经開始收费了大家能够去搜索引擎找曾经的免费版Copssh_4.1.0下 ...

  10. Wix打包系列(七) 添加系统必备组件的安装程序

    原文:Wix打包系列(七) 添加系统必备组件的安装程序 我们知道在vs的打包工程中添加系统必备组件是一件很容易的事情,那么在wix中如何检测系统必备组件并在安装过程中安装这些组件.这里以.Net Fr ...