Java代码优化六大原则
单一职责
代码优化第一步,单一职责原则 (Single Responsibility Principle)。对于一个Java类,应该仅有一个引起它变化的原因,也就是说,一个类中,应该是一组相关性很高的函数、数据的封装。但是这个原则的界限划分的并不是那么清晰,很大程度上要依赖于开发者的个人经验来定。对于单一职责界限的划分最大的问题就是类的职责是什么,如何划分类的职责。 单一职责原则在我们实际工作中随处可见,例如在我们比较关心的框架MVC,MVP中,负责页面展示的Activity,Fragment,以及各种View,它们只负责UI的展示,具体的业务逻辑则交付给Controller或者Presenter.。再例如各种流行的图片加载框架,在其中都可以找到专门负责图片加载类,图片缓存的类。所以,单一职责原则是我们代码优化的第一步,也是最重要的一步。
开闭原则
开闭原则(Open Close Principle),是Java世界里最基础的设计原则,它指导我们如何建立一个稳定、灵活的系统。开闭原则定义:软件中的对象(类,模块、函数等)应该对于扩展是开放的,对于修改的封闭的。在软件的生命周期内,因为变化、升级、维护等原因需要对软件原有的代码进行修改时,可能会将错误引入原本已经测试过的旧代码,破坏原有系统,因此,当软件需要变化时,我们应该进肯能通过扩展的方式来实现变化,而不是通过修改已有的代码来实现。但这也不是绝对的,在实际开发过程中,只通过继承的方式来升级、维护原有系统是一个理想化的情况,因此,实际开发中,修改原有代码、扩展代码往往是同时存在的。而如何确保原有软件模块的正确性,以及尽量少地影响原有代码模块,答案就是尽量遵守开闭原则。
里氏替换原则
里氏替换原则(Liskov Substitution Principle),定义:如果对于每一个类型为ClassA的对象a,都有类型为ClassB的对象b,使得以ClassB定义的所有程序P在所有的对象b都替换成a时,程序P的行为没有发生变化,那么类型ClassA是类型ClassB的子类型。然而这段叙述并无卵用,更直接的定义是:所有引用基类的地方必须能透明的使用其子类的对象。
我们知道,面向对象的三大特点是:继承,封装,多态,里氏替换原则就是依赖于继承、多态这两大特性。里氏替换原则简单来说就是,所有引用基类的地方,必须能使用子类对象。也就是说只要父类能出现的地方,其子类就可以出现。而且替换为子类不会产生任何错误和差异。使用者可能根部就不需要知道是父类还是子类,但是反过来就行不了,有子类出现的地方父类未必就能适应。其实归根结底,里氏替换原则就是基于这两个字:抽象
例如在Android中,页面Window的展示依赖于View,而View定义了一个视图抽象,measure以及draw是其子类共享的方法,子类通过复写measure以及draw方法,可实现各式各样功能以及视图的view,任何继承自View的子类都可以传递给Window,由Window负责组织View,并将View显示到屏幕上,这就是所说的里氏替换原则。
里氏替换原则的核心原理是抽象,抽象又依赖于继承,在OOP当中,继承的优缺点都相当明显。优点是:
代码重用,减少创建类的成本,每个子类都拥有父类的方法和属性
子类和父类基本相似,但又与父类有所区别
提高代码的可扩展性
继承的缺点:
继承是入侵性的,只要继承就必须拥有父类的所有属性和方法
可能造成子类代码冗余,灵活性降低,因为子类必须拥有父类的方法和属性
但事物总有两面性,符合权衡和利用都是需要根据具体情况来做出选择。在开发过程中运用抽象是走向代码优化的重要一步。
依赖倒置原则
依赖倒置原则(Dependence Inversion Principle),依赖倒置原则指定了一种特定的解耦形式,使得高层次的模块不依赖于低层次的模块的实现细节的目的,依赖模块被颠倒了。然而定义往往的不好理解的,依赖倒置原则有以下几个关键点:
高层模块不应该依赖低层模块,两者都应该依赖其抽象
抽象不应该依赖细节
细节应该依赖抽象
在Java 语言中,抽象就是指接口或抽象类,两者都是不能直接被实例化的。细节就是实现类,实现接口或继承抽象类而产生的类就是细节,其特点是,可以直接被实例化。高层模块就是调用端,低层模块就是具体实现类。依赖倒置原则在Java语言中的表现就是:模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系是通过接口或实现类产生的。其实一句话就是:面向接口,或者面向抽象编程。 如果类于类直接依赖于细节,那么它们之间就有直接耦合,当具体实现需要变化时,意味着要同时修改依赖者的代码,这限制了系统的可扩展性。
接口隔离原则
接口隔离原则(Interface Segregation Principle),它的定义是:客户端不应该依赖它不需要的接口。另一种定义是:类间的依赖关系应该建立在最小的接口上。接口隔离原则将非常庞大,臃肿的接口拆分成更小的接口和更具体的接口,这样客户只需要知道他们感兴趣的方法。接口隔离原则的目的是系统解开耦合,从而容易重构、更改和重新部署。
定义总是不好理解的,我们通过一段代码来理解一下接口隔离原则的具体使用。比如我们常见的输出流OutputStream,使用之后需要将其关闭:
FileOutputStream fos = null;
try{
fos = new FileOutputStream(URI);
...
}catch(FileNotFoundException e){
e.printStackTrace();
}finally{
if(fos!=null) {
try{
fos.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
我们看到,这段代码的可读性非常差,各种try catch嵌套的都是极其简单的代码,那么我们如何解决这个问题呢?在Java中有一个Closeable接口:
public interface Closeable extends AutoCloseable {
/**
* Closes this stream and releases any system resources associated
* with it. If the stream is already closed then invoking this
* method has no effect.
*
* @throws IOException if an I/O error occurs
*/
public void close() throws IOException;
}
该接口标识了一个可关闭的对象,它只有一个close方法,而我们的FileOutputStream也实现了这个接口。这样我们就好办了,我们可以依赖Closeable 接口实现一个工具类:
public final class CloseUtils{
private CloseUtils(){}
public static void closeQuietly(Closeable closeable){
if(null!=closeable){
try{
closeable.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
}
在实际的运用中,我们只需要这样:
...
finally{
CloseUtils.closeQuietly(fos);
}
代码简洁了很多,而且这个工具类可以运用到各类可关闭的对象中,保证了代码的重用性。CloseUtils的closeQuietly方法的基本原理就是依赖于CLoseable抽象而不是具体实现,并且建立在最小化依赖原则的基础上,它只需要知道这个对象是可关闭的,其他的一概不关心,也就是我们所提出的接口隔离原则。
迪米特原则
迪米特原则(Law of Demeter),也成为最少知识原则:一个对象应该对其他对象有最少的了解。也就是说,一个类应该对自己需要耦合或者调用的类知道的最少,类的内部如何实现与调用者或者依赖者没关系,调用者和依赖者只需要知道它需要的方法即可,其他的一概不管。类与类的关系越密切,耦合度越大,当一个类发生改变时,对另一个类的影响也越大。
就比如说MVP框架中的Model层的实现,我们都知道Model抽象是给View提供具体的数据,而我们的View层并不需要知道数据是怎么得来的,就算我们后台接口如何改变,只要数据结构不变,那我们就不需要通知View层进行改变。
Java代码优化六大原则的更多相关文章
- Java设计模式六大原则-2
Java设计模式六大原则-2 做Java程序开发的每天都在使用JDK,Spring,SpringMvc,Mybatis,Netty,MINA等框架,但很少有人懂得背后的原理.即使打开跟下原码也是一头雾 ...
- Java设计模式六大原则-1
Java设计模式六大原则-1 做Java程序开发的每天都在使用JDK,Spring,SpringMvc,Mybatis,Netty,MINA等框架,但很少有人懂得背后的原理.即使打开跟下原码也是一头雾 ...
- Java基础学习总结(84)——Java面向对象六大原则和设计模式
面向对象六大原则 在此之前,有一点需要大家知道,熟悉这些原则并不是说你写出的程序就一定灵活.清晰,只是为你优秀的代码之路铺上了一层栅栏,在这些原则的指导下,你才能避免陷入一些常见的代码泥沼,从而让你写 ...
- Java设计模式六大原则
一.单一职责原则 单一职责原则是最简单的面向对象设计原则,它用于控制类的粒度大小.单一职责原则定义如下: 单一职责原则(Single Responsibility Principle, SRP):一个 ...
- Java设计模式六大原则之场景应用分析
定义:不要存在多于一个导致类变更的原因. 通俗的说.即一个类仅仅负责一项职责. 问题由来:类T负责两个不同的职责:职责P1,职责P2.当由于职责P1需求发生改变而须要改动类T时,有可能会导致原本执行正 ...
- Java面向对象六大原则
引用自百度知道: ——根据首字母快速记忆SOLID(固体,坚固的),具体请参考这里 1) Open-Close Principle(OCP),开-闭原则, 讲的是设计要对扩展有好的支持,而对修改要严格 ...
- java设计模式--六大原则
一.单一职责原则 单一职责原则:就一个类而言,应该仅有一个引起它变化的原因.通俗来说,就是互相不相关的属性和方法不要放在一个类中,就好比之前简单工厂模式中介绍的那样,客户端(Customer)应该与工 ...
- Java 设计模式(二)-六大原则
Java 设计模式(二)-六大原则 单一职责原则(Single Responsibility Principle) 定义: 不要存在多余一个原因导致类变更,既一个类只负责一项职责. 问题由来: 当类A ...
- Java设计模式面试题 01 - 六大原则
Java设计模式面试题 01 - 六大原则 1. 单一职责原则 Single Responsibility Principle SRP原则 分清职责,接口一定要做到单一职责,方法也要做到,类尽量做到 ...
随机推荐
- Ajax请求汇总(一)
刚开始结束Ajax请求的时候,那真的是迷迷糊糊,昏天暗地,通过学习的深入和翻阅各种资料.求助度娘,总结一下Ajax请求,与大家分享一下,希望能给学习Ajax的同学一些帮助,废话不多手,直接开始~~~ ...
- 读《深入理解Java虚拟机》
Java虚拟机运行时数据区 对象的创建 Java创建对象,在语言层面上使用new关键字.虚拟机遇到new关键字时,会检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的 ...
- 浏览器本地储存方式有哪些?cookie、localStorage、sessionStorage
现阶段,浏览器提供的储存方式常用的有三种,cookie.localStorage.sessionStorage 1.cookie 概念:cookie 是浏览器中用于保存少量信息的一个对象 基本特征: ...
- C++经典绘图工具EasyX
EasyX简介 EasyX 在学习C语言时,很多同学抱怨说C只能写最简单的Demo程序,通过printf在屏幕上打印字符来验证代码.这样的编程很枯燥,一点没觉得自己在设计软件. EasyX是针对C++ ...
- python读写文件相关内容
1.python读取文件 f = open('E:/info.txt', 'r')#用read的方式打开a = 0for line in f.readlines():读取没一行,就是读取所有文件的意思 ...
- lucene全文搜索之四:创建索引搜索器、6种文档搜索器实现以及搜索结果分析(结合IKAnalyzer分词器的搜索器)基于lucene5.5.3
前言: 前面几章已经很详细的讲解了如何创建索引器对索引进行增删查(没有更新操作).如何管理索引目录以及如何使用分词器,上一章讲解了如何生成索引字段和创建索引文档,并把创建的索引文档保存到索引目录,到这 ...
- win7安装oracle10g数据库 提示“…实际版本为6.1”
1.最重要的是需要以管理员的身份操作 2.修改重要的文件 然后解压,在目录中找到refhost.xml(有两个,我的一个是在stage\prereq\db目录下,一个是在stage\prereq\db ...
- POJ 1459-Power Network(网络流-最大流-ISAP)C++
Power Network 时间限制: 1 Sec 内存限制: 128 MB 题目描述 A power network consists of nodes (power stations, cons ...
- webpack前端工程化构建工具的使用
一.模块打包机 1.创建文件 在目标文件下建立一个src文件夹作为js代码区:作为例子,我创建了两个js文件,并利用commonJS规范require引入到index.js中: moduleA.js: ...
- linux下安装QT5:error: unrecognized command line option ‘-fuse-ld=gold’
安装qt时在执行./configure时报错:error: unrecognized command line option '-fuse-ld=gold' 这个错误是qt的一个bug. 在装有gol ...