zoukankan      html  css  js  c++  java
  • UML之轻松入门(3)-SRP做好厨子,让别人编程去吧

         一个厨子能够做出一手好菜,或许他是新东方毕业的或者是祖传秘方。你让他做上一桌佳肴那是简单、快乐而又高效的,然而让他编程就会成为一种苦恼并且让人想不通的一件事。或许这个比喻不是非常恰当,可是对于每一个类来说,他们就像一个一个的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原则


  • 相关阅读:
    184. Department Highest Salary【leetcode】sql,join on
    181. Employees Earning More Than Their Managers【leetcode】,sql,inner join ,where
    178. Rank Scores【leetcode】,sql
    177. Nth Highest Salary【leetcode】,第n高数值,sql,limit,offset
    176. Second Highest Salary【取表中第二高的值】,sql,limit,offset
    118. Pascal's Triangle【LeetCode】,java,算法,杨辉三角
    204. Count Primes【leetcode】java,算法,质数
    202. Happy Number【leetcode】java,hashSet,算法
    41. First Missing Positive【leetcode】寻找第一个丢失的整数,java,算法
    删除
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/3986592.html
Copyright © 2011-2022 走看看