对JAVA代码设计六大原则的理解

来源:互联网 发布:mp3转换器软件下载 编辑:程序博客网 时间:2024/05/22 10:32

对JAVA代码设计六大原则的理解

记得有一次去面试的时候,面试官问了我好几个问题,很尴尬,好几个都没能流利得回答上来。对其中有一个问题比较深刻,他当时是这样问我的:说下代码优化的6大原则,我当时一听,在脑子里快速想了下,很遗憾,不知道。今天想起了这个事,决定一定要搞定这个问题,一是了解这个问题,其次也是为下一次面试做准备
在网上搜了下后,知道了主要是以下六大原则:

  • 单一职责
  • 开闭原则
  • 里氏替换原则
  • 依赖倒置原则
  • 接口隔离原则
  • 迪米特法则

了解了后,记得去年在QQ群里下的一本叫《您的设计模式》电子书上有见过这几个原则。对于那本书的记忆,目前只记得当时一心都在设计模式上,再加上那本书写得真心不错,针对每一种设计模式,都用了浅显有趣的故事来讲解的,很方便理解,看到了后面有介绍这几种原则时,只在脑子里过了一遍,并没有对此进行深入的思考,而没想到,在面试时,居然用到了。面试时没能答出,顿时让我体会到了“书到用时方恨少”的真谛。

看了下网上的解释后,结合着以往的的开发编码经验,总结下我对这六大原则的理解

单一职责原则(Single Responsibility Principle)

顾名思义,有点物以类聚,人以群分的感觉。一个类或一个方法应该只负责它应该负责的东西。比如有一个类:loginController那么在此类中,就只写一些关于登录的相关代码,不要在这个类里又写和登录不相关的功能点,这样很便于代码的维护

开闭原则(Open Close Principle)

仍然从字面意思中理解,主要是开闭这两个字。
开:对于代码的功能扩展是开放的
闭:对于已经定好的功能点,对于以后的修改应该是出于封闭的
总的来说,就是在代码设计上,要对功能的扩展提供可扩展的空间,如spring的AOP的实现就很方便,对于处理可以一直扩展;又比如责任链模式,对于某一职责提供可预留的空间给将来的功能点,spring mvc中的interceptor、web中的filter、netty中的channel等都是很好的设计;
而对于已写好的代码要做好闭,如用private修饰,阻止外界调用,用final修饰不让其重写,比如单例模式时,常用private修饰构造函数,避免其他类又生成新的对象

里氏替换原则(Liskov Substitution Principle)

这个名字,刚开始我觉得怪怪的。我想:替换原则就替换原则嘛,为啥还叫个里氏原则。在了解了后,才知道这个原则原来是由2008年图灵奖得主,2004年约翰·冯诺依曼奖得主的麻省理工学院教授芭芭拉·利斯科夫(Barbara Liskov)在1988年提出的,只看她的获奖经历,也不得不佩服了,(图灵奖,冯诺依曼奖这种在大学计算机课程中常看到的奖项,觉得顿时好厉害好强的感觉)让我也觉得这个替换原则用她的名字来命名非常合适,毕竟是大人物!
里氏替换原则,我觉得不好从字面意思来理解了,看了好几遍解释后,我才慢慢消化这个原则。此原则是这样说的:If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is substituted for o2 then S is a subtype of T.
翻译下:如果对每一个类型为 T1的对象 o1,都有类型为 T2 的对象o2,使得以 T1定义的所有程序 P 在所有的对象 o1 都代换成 o2 时,程序 P 的行为没有发生变化,那么类型 T2 是类型 T1 的子类型
这段话我理解了半天,感觉不愧是外国人发明的,确实有点打脑壳。其实就是说:任何基类可以出现的地方,子类一定可以出现
我是这样理解的:对于一个拥有继承关系的类中,父类换成这个类的子类后,对以前的功能没有任何影响,也就是子类不要去重写(overWrite)父类的非抽象(abstract)方法。比如设计模式中的模板方法模式,设计时把模板方法定义为final,从而避免子类对方法的重写

依赖倒置原则(Dependence Inversion Principle)

依赖于抽象而不依赖于具体。不与具体类交互,而与具体类的上层接口交互。
这个比较好理解,平时在开发JAVA EE这程序中用到的也最多。也就是所谓的面向接口编程
比如定义一个UserService接口,其实现类为UserServiceImpl,而我们需要调用时,都是这样写的UserService userService = new UserviceImpl(),或通过Spring的IOC注入进去对象。这种设计在spring的IOC框架中得到了充分体现,当然系统的许多集合类也是这样的,又如Set set = new TreeSet();List list = new ArrayList()等

接口隔离原则(Interface Segregation Principle)

类间的依赖关系应该建立在最小的接口上
接口隔离原则感觉和单一职责原则很类似,都强调了物以类聚的概念。但其针对的对象与维度不一样,单一职责主要是针对于一个类的,强调了类的功能。而接口隔离原则有更细化的感觉。

迪米特法则(Demeter Principle)

又叫作最少知道原则
这个名字刚开始也让我觉得怪怪的,迪米特?什么东东。
想要了解这个法则,就要先了解迪米特(Demeter的音译)。在网上查阅了相关的资料后,并没有找到它具体的由来。在百度里看到了这个词条:德墨忒尔(Demeter)是希腊神话中司掌农业的谷物女神,亦被称为丰收女神。
女神嘛,你懂的,就是很高端大气上档次,总能给人一种很难接近的感觉,熟悉而又陌生,只知道她的外表,不知道内在(个人理解,纯胡编乱造)
迪米特原则也主要是这个意思:一个对象应当对其他对象有尽可能少的了解,不和陌生人说话
其实现在许多框架中也比较多了,比如SpringBoot就充分体现了这种原则,只暴露出几个类和方法,对于其实现的细节进行了很好的封装,这点又体现了开闭原则中的闭的特点。设计模式中的门面模式(Facade Pattern)也很好的体现了这一原则。


对上是我对JAVA代码设计六大原则的个人理解,其中难免有许多理解不当的地方,往各种指正!在下感激不尽!

原创粉丝点击