单一职责

代码优化第一步,单一职责原则 (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代码优化六大原则的更多相关文章

  1. Java设计模式六大原则-2

    Java设计模式六大原则-2 做Java程序开发的每天都在使用JDK,Spring,SpringMvc,Mybatis,Netty,MINA等框架,但很少有人懂得背后的原理.即使打开跟下原码也是一头雾 ...

  2. Java设计模式六大原则-1

    Java设计模式六大原则-1 做Java程序开发的每天都在使用JDK,Spring,SpringMvc,Mybatis,Netty,MINA等框架,但很少有人懂得背后的原理.即使打开跟下原码也是一头雾 ...

  3. Java基础学习总结(84)——Java面向对象六大原则和设计模式

    面向对象六大原则 在此之前,有一点需要大家知道,熟悉这些原则并不是说你写出的程序就一定灵活.清晰,只是为你优秀的代码之路铺上了一层栅栏,在这些原则的指导下,你才能避免陷入一些常见的代码泥沼,从而让你写 ...

  4. Java设计模式六大原则

    一.单一职责原则 单一职责原则是最简单的面向对象设计原则,它用于控制类的粒度大小.单一职责原则定义如下: 单一职责原则(Single Responsibility Principle, SRP):一个 ...

  5. Java设计模式六大原则之场景应用分析

    定义:不要存在多于一个导致类变更的原因. 通俗的说.即一个类仅仅负责一项职责. 问题由来:类T负责两个不同的职责:职责P1,职责P2.当由于职责P1需求发生改变而须要改动类T时,有可能会导致原本执行正 ...

  6. Java面向对象六大原则

    引用自百度知道: ——根据首字母快速记忆SOLID(固体,坚固的),具体请参考这里 1) Open-Close Principle(OCP),开-闭原则, 讲的是设计要对扩展有好的支持,而对修改要严格 ...

  7. java设计模式--六大原则

    一.单一职责原则 单一职责原则:就一个类而言,应该仅有一个引起它变化的原因.通俗来说,就是互相不相关的属性和方法不要放在一个类中,就好比之前简单工厂模式中介绍的那样,客户端(Customer)应该与工 ...

  8. Java 设计模式(二)-六大原则

    Java 设计模式(二)-六大原则 单一职责原则(Single Responsibility Principle) 定义: 不要存在多余一个原因导致类变更,既一个类只负责一项职责. 问题由来: 当类A ...

  9. Java设计模式面试题 01 - 六大原则

    Java设计模式面试题 01 - 六大原则 1. 单一职责原则 Single Responsibility Principle SRP原则 分清职责,接口一定要做到单一职责,方法也要做到,类尽量做到 ...

随机推荐

  1. docker安装与学习

    docker学习 以ubuntu为实例 第一步检查系统内核>3.80 第二步 安装Docker 之前先更新apt-get update 在执行安装命令 apt-get install -y do ...

  2. HTML5之2D物理引擎 Box2D for javascript Games 系列 第三部分之创建图腾破坏者的关卡

    创建图腾破坏者的关卡 现在你有能力创建你的第一个游戏原型,我们将从创建图腾破坏者的级别开始. 为了展示我们所做事情的真实性,我们将流行的Flash游戏图腾破坏者的一关作为 我们模仿的对象.请看下面的截 ...

  3. a标签实现文件下载

    如果想通过纯前端技术实现文件下载,直接把a标签的href属性设置为文件路径即可,如下: <a href="https://cdn.shopify.com/s/files/1/1545/ ...

  4. h5 + nginx + php 视频上传之突破文件大小受限的解决办法

    一.环境: CentOS 6.8 nginx 1.8.0 php 7.0.10 二.背景 基于 nginx + php 的 h5 项目,上传视频的时候,如果视频太大,会上传失败. 三.正文 一份视频传 ...

  5. 使用外部容器运行spring-boot项目:不使用spring-boot内置容器让spring-boot项目运行在外部tomcat容器中

    前言:本项目基于maven构建 spring-boot项目可以快速构建web应用,其内置的tomcat容器也十分方便我们的测试运行: spring-boot项目需要部署在外部容器中的时候,spring ...

  6. APUE-文件和目录(五)函数rename和renameat

    rename和renameat #include <stdio.h> int rename(const char *oldname,const char*newname); int ren ...

  7. OWIN的概念初接触

    OWIN这个词我昨天才认识,一直疑惑它是个什么东西,通过一定量的研究,得到一个初步的认识,留个脚印. OWIN是什么 OWIN是一个规范和标准,旨在阐述web服务器和web应用应该如何去解耦,它使得原 ...

  8. WindowManager.LayoutParams的探究

    上次在子线程更新UI时用了一下WindowManager.LayoutParams,当时觉得不太顺手.以前都是用空参构造器,这次用了type和flag属性,出现了意想不到的效果.也看看源码吧,多锻炼锻 ...

  9. 在Cenos系统安装Python3.5版本,使P2和P3共存

    首先Cenos安装好后,系统自带python2.6版本 输入>>>exit()     退出 使用迅雷下载python3.5 链接:https://www.python.org/ft ...

  10. zookeeper client API实现(python kazoo 的实现)

    这里主要分析zookeeper client API的实现方式,以python kazoo的实现代码为蓝本进行逻辑分析. 一.代码框架及介绍 API分为同步模式和异步模式.同步模式是在异步模式的基础上 ...