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原则 分清职责,接口一定要做到单一职责,方法也要做到,类尽量做到 ...
随机推荐
- 在ie下,a标签包被img的时候,为什么有个蓝色的边线
效果像下图这样 那是由于<img>在ie下有默认边框,只要清除边框就可以了,在style中定义 img{ border:none } 显示效果就变成下面这样了 完!
- mac安装as配置
/Users/admin/Library/Android/sdk export PATH=${PATH}:/Users/admin/Library/Android/sdk/tools:/Users/a ...
- Vulkan Tutorial 11 Shader modules
操作系统:Windows8.1 显卡:Nivida GTX965M 开发工具:Visual Studio 2017 与之前的图像API不同,Vulkan中的着色器代码必须以二进制字节码的格式使用,而不 ...
- spring管理配置文件的工厂类--PropertiesFactoryBean
使用这个工厂的配置,可以很方便的获取配置文件中的属性.具体使用如下; 对于属性配置,一般采用的是键值对的形式,如: key=value 属性配置文件一般使用的是XXX.properties,当然有时候 ...
- hibernate配置三步走
1.导入有hibernate的required和jpa的jar包,数据库驱动jar包,日志jar包 2.创建实体类,必须有一个属性有唯一的值 package com.hui.hibernate; pu ...
- js实现整数转化为小数
toFixed 方法 返回一个字符串,代表一个以定点表示法表示的数字. number .toFixed(i) 参数 bumber 必选项.一个 Number 对象. i 可选项.小数点 后的数字位数. ...
- RabbitMQ系列教程之三:发布/订阅(Publish/Subscribe)
(本教程是使用Net客户端,也就是针对微软技术平台的) 在前一个教程中,我们创建了一个工作队列.工作队列背后的假设是每个任务会被交付给一个[工人].在这一部分我们将做一些完全不同的事情--我们将向 ...
- EF架构~Migration数据迁移的执行顺序
回到目录 对于单个分支项目来说,只要你生成一个migration的版本,就会有一个时间戳文件的对应,而在update-database时,会从最小的时间开始,一直执行到当前版本的migration,而 ...
- JVM中class文件探索与解析(一)
一直想成为一名优秀的架构师的我,转眼已经工作快两年了,对于java内核了解甚少,闲来时间,看看JVM,吧自己的一些研究写下来供大家参考,有不对的地方请指正. 废话不多说,一起来看看JVM中类文件是如何 ...
- memcached可视化客户端工具
TreeNMS是一款redis,Memcache可视化客户端工具,采用JAVA开发,实现基于WEB方式对Redis, Memcached数据库进行管理.维护. 功能包括:NoSQL数据库的展示,库表的 ...