程序员这行干的久了,总会染上一些恶习,我就染上一个让人深恶痛绝,自己却津津乐道的习惯,还不想改的那种,它可以叫做强迫症,也可以叫做洁癖。那就是我不允许我的IDEA出现一点点警告,什么黄色背景,绿色波浪线,统统不允许,按下F2键必须是这样

当然,说这些也没有意义,因为并没有说如何去做,所以今天我准备开一个新的系列——如何写出高效清爽的Java代码,这意味着这整个系列的所有案例都会十分严谨且苛刻。如果有小伙伴说:这一丁点性能有什么嘛,无所谓啦。我:不,一丁点也不允许!

高效:开发高效,性能高效

今天是第一篇——使用静态工厂方法代替构造器

名字的重要性

一千个人眼里有一千个哈姆雷特,一千个项目里有个一千个通用响应对象,比如ApiResponseResponseResultBaseResult 等等,它们的结构一般都像这样

public class BaseResult<T> implements Serializable {

    private static final long serialVersionUID = -9127050844792378533L;

    /**
* 状态码
*/
private int code; /**
* 消息
*/
private String message; /**
* 需要返回的数据对象
*/
private T data; public BaseResult() {
} public BaseResult(int code, String message) {
this(code, message, null);
} public BaseResult(int code, String message, T data) {
this.code = code;
this.message = message;
this.data = data;
}
// 省略get/set方法
}

一般我们会定义code为0,或者200什么的表示正确响应,其他的为错误响应。

使用的示例如下:

public BaseResult<Order> getOrder(){
Order order = new Order();
return new BaseResult<>(0, "成功", order);
}

这样子使用咋一看好像没什么问题,那是因为我先告诉大家code=0是正确,再给出相应的示例,如果小伙伴直接看示例多半会懵住:0是指什么?因为0在这里是个魔法值。或者说,正确的响应码发生变更,项目经理说,code=0太不好看了,改成200!这个时候...完蛋。

这时候我们可以多加一个专门用来描述code的类,如:

public interface ResultCode {
/**
* 正确响应码
*/
int SUCCESS = 0;
/**
* 错误响应码
*/
int FAILURE = -1;
}

使用方式就发生了变更:

public BaseResult<Order> getOrder(){
Order order = new Order();
return new BaseResult<>(ResultCode.SUCCESS, "成功", order);
}

现在,我们消除了魔法值,而且不管项目经理说把code改成啥都行,我们只改ResultCode.SUCCESS的值就行。

项目经理:code改成字符类型!

但是!如果每个接口的返回值都这样写,就会发现,整个项目都充斥这new BaseResult<>(ResultCode.SUCCESS, "成功", value)这样的语句,这一行代码只有value不一样,其他全都一模一样,啊,这丑陋的代码。

于是,我们继续改进,增加两个静态方法:

public static <T> BaseResult<T> success(T data){
return new BaseResult<>(ResultCode.SUCCESS, ResultCode.SUCCESS_MESSAGE, data);
} public static BaseResult<Void> failure(){
return new BaseResult<>(ResultCode.FAILURE, ResultCode.FAILURE_MESSAGE);
}

在ResultCode类中增加两个常量:

String SUCCESS_MESSAGE = "成功";
String FAILURE_MESSAGE = "失败";

如果每次new BaseResult<>(ResultCode.SUCCESS, "成功", order)的话, 成功这个字符串则会随着每次new出BaseResult而创建出一个字符串对象。

改进后的使用方式:

public BaseResult<Order> getOrder(){
Order order = new Order();
return BaseResult.success(order);
}

使用者再也不需要关心code是啥,cool~

项目经理:给我把code改.... 开发:啪(巴掌声)

不必每次构建都创建对象

有时候调用的接口不需要返回参数,只需要响应一个正确或者失败即可,此时我们就需要一个无参的success方法:

public static BaseResult<Void> success(){
return new BaseResult<>(ResultCode.SUCCESS, ResultCode.SUCCESS_MESSAGE);
}

使用:

public BaseResult<Void> createOrder(){
return BaseResult.success();
}

不知道小伙伴有没有发现一个问题,这个无参的success方法每次返回的对象都是相同的,但是每次都创建了一个新的对象出来!啊,糟糕的代码!

改进:

public static final BaseResult<Void> SUCCESS = new BaseResult<>(ResultCode.SUCCESS, ResultCode.SUCCESS_MESSAGE);
public static final BaseResult<Void> FAILURE = new BaseResult<>(ResultCode.FAILURE, ResultCode.FAILURE_MESSAGE); public static BaseResult<Void> success(){
return SUCCESS;
}
public static BaseResult<Void> failure(){
return FAILURE;
}

这里顺手把failure方法也改进一下

现在,每次调用无参success`方法时都使用一个静态对象,不再发生重复创建!爽!

注意,需要data数据的BaseResult不要这样做,否则会出现线程安全问题

闭环

有时候接口不仅会与页面交互,服务与服务之间也会产生交互,这时候如果我们想要判断其他接口的响应情况,会怎么做呢?

public void callOtherServer(){
BaseResult<Void> result = createOrder();
if(result.getCode() == ResultCode.SUCCESS){
// 正确
}
}

现阶段我们只能这样做,啊,这糟糕的代码又出现了!

改进:

public boolean isSuccess(){
return this.code == ResultCode.SUCCESS;
} public boolean isFailure(){
return this.code != ResultCode.SUCCESS;
}

改进后的使用方式:

public void callOtherServer(){
BaseResult<Void> result = createOrder();
if(result.isSuccess()){
// 正确
}
}

优雅的代码!

小结

本篇介绍了关于使用静态工厂方法代替构造器的美好事情

第一:使用一个好名字对构造逻辑进行封装

第二:有时候并不需要每次重复的创建对象

第三:建立一个逻辑闭环

学会了的小伙伴看看自己的项目有没有改进的空间吧~

原创地址:https://zijiancode.cn/archives/usestaticmethod

看完之后想必有所收获吧~ 想要了解更多精彩内容,欢迎关注公众号:程序员阿鉴,阿鉴在公众号欢迎你的到来~

高效JAVA之用静态工厂方法代替构造器的更多相关文章

  1. 改善JAVA代码01:考虑静态工厂方法代替构造器

    前言 系列文章:[传送门]   每次开始新的一本书,我都会很开心.新书新心情. 正文 静态工厂方法代替构造器 说起这个,好多可以念叨的.做了一年多的项目,慢慢也有感触. 说起构造器 大家很明白,构造器 ...

  2. Java - 用静态工厂方法代替构造器

    Effective Item - 考虑用静态工厂方法代替构造器我们有两种常见的方法获得一个类的实例: 公有的构造器 提供静态工厂方法(static factory method) 相对公有的构造器,静 ...

  3. Effective Java 读书笔记(一):使用静态工厂方法代替构造器

    这是Effective Java第2章提出的第一条建议: 考虑用静态工厂方法代替构造器 此处的静态工厂方法并不是设计模式,主要指static修饰的静态方法,关于static的说明可以参考之前的博文&l ...

  4. effective java 3th item1:考虑静态工厂方法代替构造器

    传统的方式获取一个类的实例,是通过提供一个 public 构造器.这里有技巧,每一个程序员应该记住.一个类可以对外提供一个 public 的 静态工厂方法 ,该方法只是一个朴素的静态方法,不需要有太多 ...

  5. 【Effective Java读书笔记】创建和销毁对象(一):考虑使用静态工厂方法代替构造器

    类可以提供一个静态方法,返回类的一个静态实例,如Boolean包装类的一个获取实例的静态方法 public static Boolean valueOf(boolean b) { return (b ...

  6. Effective java读书札记第一条之 考虑用静态工厂方法取代构造器

    对于类而言,为了让client获取它自身的一个实例,最经常使用的方法就是提供一个共同拥有的构造器. 另一种放你发,也应该子每一个程序猿的工具箱中占有一席之地.类能够提供一个共同拥有的静态 工厂方法.它 ...

  7. 【读书笔记 - Effective Java】01. 考虑用静态工厂方法代替构造器

    获取类的实例有两种方法: 1. 提供一个公有的构造器(最常用). 2. 提供一个公有的静态工厂方法(static factory method). // 静态工厂方法示例 public static ...

  8. 静态工厂方法VS构造器

    我之前已经介绍过关于构建者模式(Builder Pattern)的一些内容,它是一种很有用的模式用于实例化包含几个属性(可选的)的类,带来的好处是更容易读.写及维护客户端代码.今天,我将继续介绍对象创 ...

  9. Tips1:考虑用静态工厂方法代替构造器

    用静态工厂方法来代替构造器为外界提供对象 描述: 静态工厂方法代替构造器来给外界提供对象,创建对象依然是由构造器来完成的 创建对象和提供对象: 创建对象的方式: 构造器 提供对象来哦方式: 构造器 类 ...

随机推荐

  1. es6快速入门 系列 - async

    其他章节请看: es6 快速入门 系列 async 前文我们已经知道 promise 是一种异步编程的选择.而 async 是一种用于执行异步任务更简单的语法. Tip:建议学完 Promise 在看 ...

  2. C++调用Libreoffice接口

    由于部分原因,只提供cpp文件,其中代码还需要优化 其中主要涉及了Excel的创建 Sheet页的增加.删除.重命名 表格的合并 表格背景.边框部分属性的设置 表格内字体部分属性设置 表格内容的读取和 ...

  3. centos使用yum安装docker

    1.先决条件 要安装 Docker 引擎,您需要 CentOS 7 或 8 的维护版本.不支持或测试存档版本. 该centos-extras库必须启用.默认情况下启用此存储库,但如果您已禁用它,则需要 ...

  4. AcWing 341. 最优贸易

    C国有 n 个大城市和 m 条道路,每条道路连接这 n 个城市中的某两个城市. 任意两个城市之间最多只有一条道路直接相连. 这 m 条道路中有一部分为单向通行的道路,一部分为双向通行的道路,双向通行的 ...

  5. HADOOP及SPARK安装步骤及问题解决

    说明:主节点IP:192.168.35.134   主机名:master 从节点slave1 IP: 192.168.35.135   主机名:slave1 从节点slave2 IP: 192.168 ...

  6. buu Youngter-drive

    一.查壳,发现是upx的壳,用自解压方式,脱下壳 二.之后发现打不开了,应该是要修复,不想修复了,直接拖入ida 找到关键函数,中间发生一点小插曲,发现堆栈不平衡,然后导致F5反编译失败,百度了下是A ...

  7. C# 8.0和.NET Core 3.0高级编程 分享笔记二:编程基础第一部分

    基础部分被我分为了2篇,因为实在太多了,但是每一个知识点我都不舍得删除,所以越写越多,这一篇博客整理了4个夜晚,内容有点多建议慢慢看.本章涵盖以下主题: 介绍C# 理解C#的基础知识 使用变量 处理空 ...

  8. SQL关联子查询

    SQL关联子查询执行顺序: 1.先取到主查询中的相关数据,一次取一行主查询的数据 2.然后传入子查询,进行子查询 3.最后做主查询where筛选,注意子查询的where条件同样需要加在主查询后 参考: ...

  9. java基础---集合(2)

    一. Set 集合 java.util.Set集合是Collection集合的子集合,与List集合平级.该集合中元素没有先后放入次序,且不允许重复. 存储的数据在底层数组中并非按照数组索引的顺序添加 ...

  10. Python装饰器、迭代器&生成器、re正则表达式、字符串格式化

    Python装饰器.迭代器&生成器.re正则表达式.字符串格式化 本章内容: 装饰器 迭代器 & 生成器 re 正则表达式 字符串格式化 装饰器 装饰器是一个很著名的设计模式,经常被用 ...