在阅读《阿里巴巴Java开发手册》时,发现有一条关于关于常量定义的规约,具体内容如下:

图中的反例是将数据缓存起来,并使用魔法值加链路 id 组成 key,这就可能会出现其他开发人员在复制粘贴的时候,少复制 _ 的情况发生,这种错误很难去检查到,因为读取缓存不存在,可能会去数据库读取,很难察觉到。

如果在生产环境中,大量的请求进来,缓存全部失效,直接请求数据库,导致数据库连接过多,查询效率变低的问题发生,因此看来魔法值确实应该避免出现在代码中。

另外在 《Clean Code》 和 《重构》 等书中也提到了类似的问题,在代码中出现原始形态数字通常来说是坏现象,应该用命名良好的常量类隐藏它。

静态常量取代魔法值

像下面这个例子:

if (billCount > 75) {
//todo
} else {
//todo
}

如果在不了解这块的业务的同事,在读到这块代码的时候,可能会想,75 是什么鬼,为啥和这个数比较,背后深藏着什么秘密吗?可能只有当时的开发人员记得了,导致代码可读性和可维护性极差。

如果声明一个常量,来替换该魔法值,可能就会使代码的可读性和可维护性大大增加。

static final Integer BASIC_BILL_COUNT = 75;

还有些魔法表达式,比如:

if (value > 60 && value <= 80 && type = 1) {
// todo
}

比如这个表达式是表示状态为正常且项目活跃,就可以定义:

boolean isActiveProject = value > 60 && value <= 80 && type = 1;

这样是不是可读性就提高了,一眼就可以看出来这块代码的逻辑。

枚举类取代魔法值

还有一种消除魔法值的方式是使用枚举类代替,下面让我们举个例子:

if (eventId == 1) {
System.out.println("睡觉");
} else if (eventId == 2) {
System.out.println("吃饭");
} else if (eventId == 3) {
System.out.println("打豆豆");
}

如上代码是针对事件 id 去执行相应的事件,如果事件比较少,大家还可以勉强记住每个 eventId 对应的含义,但是随着事件 id 的增多,很可能会发生,新来的员工把事件 id 给搞混了,导致执行错误的事件,发生 bug。

那么我们可以使用枚举类来表示相应的事件:

public enum EventEnum {

    /**
* 睡觉
*/
SLEEP_EVENT(1, "睡觉"), /**
* 吃饭
*/
EAT_EVENT(2, "吃饭"), /**
* 打豆豆
*/
FIGHT_PEA_EVENT(3, "打豆豆"); private int eventId;
private String desc; EventEnum(int eventId, String desc) {
this.eventId = eventId;
this.desc = desc;
} public int getEventId() {
return eventId;
} public String getDesc() {
return desc;
}
}

修改完之后的代码如下:

if (eventId == EventEnum.SLEEP_EVENT.getEventId()) {
System.out.println("睡觉");
} else if (eventId == EventEnum.EAT_EVENT.getEventId()) {
System.out.println("吃饭");
} else if (eventId == EventEnum.FIGHT_PEA_EVENT.getEventId()) {
System.out.println("打豆豆");
}

是不是可读性急剧提升,还不快看看自己代码中有没有这样的魔法值出现,有的话赶紧改造起来。

还有如果你需要在不同的地点引用同一数值,魔法数会让你烦恼不已,因为一旦这些数字发生改变,就必须在程序中找到所有的魔法值,并将它们全部修改一遍,这样就太费时费力了。

其实不只是 Java 不应该在代码中使用魔法值,其他语言亦是如此。

总结

本文主要介绍了为什么不允许在代码中出现魔法值以及如何将代码中已有的魔法值去除掉。

代码可读性还是比较重要的,你肯定不希望别人在接手你的代码的时候,骂到这数字啥意思,这代码写得跟粑粑一样。

最好的关系就是互相成就,大家的在看、转发、留言三连就是我创作的最大动力。

参考

《Java开发手册》泰山版

为什么阿里巴巴Java开发手册中不允许魔法值出现在代码中?的更多相关文章

  1. 阿里巴巴 Java 开发手册 1.4.0

    一.编程规约(一) 命名风格1. [强制]代码中的命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束.反例: _name / __name / $name / name_ / name$ ...

  2. 阿里巴巴Java开发手册(华山版)

    插件下载地址: https://github.com/alibaba/p3c 2018年9月22日,在2018杭州云栖大会上,召开<码出高效:Java 开发手册>新书发布会,并宣布将图书所 ...

  3. 《阿里巴巴Java开发手册》代码格式部分应用——idea中checkstyle的使用教程

    <阿里巴巴Java开发手册>代码格式部分应用--idea中checkstyle的使用教程 1.<阿里巴巴Java开发手册> 这是阿里巴巴工程师送给各位软件工程师的宝典,就像开车 ...

  4. 为什么阿里巴巴Java开发手册中不建议在循环体中使用+进行字符串拼接?

    之前在阅读<阿里巴巴Java开发手册>时,发现有一条是关于循环体中字符串拼接的建议,具体内容如下: 那么我们首先来用例子来看看在循环体中用 + 或者用 StringBuilder 进行字符 ...

  5. 为什么阿里巴巴Java开发手册中强制要求整型包装类对象值用 equals 方法比较?

    在阅读<阿里巴巴Java开发手册>时,发现有一条关于整型包装类对象之间值比较的规约,具体内容如下: 这条建议非常值得大家关注, 而且该问题在 Java 面试中十分常见. 还需要思考以下几个 ...

  6. 为什么阿里巴巴Java开发手册中强制要求不要在foreach循环里进行元素的remove和add操作?

    在阅读<阿里巴巴Java开发手册>时,发现有一条关于在 foreach 循环里进行元素的 remove/add 操作的规约,具体内容如下: 错误演示 我们首先在 IDEA 中编写一个在 f ...

  7. 为什么阿里巴巴Java开发手册中强制要求接口返回值不允许使用枚举?

    在阅读<阿里巴巴Java开发手册>时,发现有一条关于二方库依赖中接口返回值不允许使用枚举类型的规约,具体内容如下: 在谈论为什么之前先来科普下什么是二方库,二方库也称作二方包,一般指公司内 ...

  8. 阿里巴巴Java开发手册———个人追加的见解和补充(一)

    先上干货,<阿里巴巴Java开发手册>的下载地址 https://yq.aliyun.com/articles/69327?spm=5176.100239.blogcont69327.15 ...

  9. 阿里巴巴Java开发手册评述

    2016年底的时候阿里巴巴公开了其在内部使用的Java编程规范.随后进行了几次版本修订,目前的版本为v1.0.2版.下载地址可以在其官方社区-云栖社区https://yq.aliyun.com/art ...

随机推荐

  1. .NET 程序员的 Playground :LINQPad

    如果想执行一个简单的 C# 语句并获得运行结果,通常我们需要做几个步骤才能达成: 打开 Visual Studio 并新建一个控制台项目. 在 Program.cs 中编写代码并保存. 点击运行按钮或 ...

  2. webpack-dev-server简记

    webpack -v 3.4.1 npm -v 3.10.10 /////////////////////////////////////// webpack的webpack-dev-server可以 ...

  3. scrapy爬取效率提升配置

    增加并发: 默认scrapy开启的并发线程为32个,可以适当进行增加.在settings配置文件中修改CONCURRENT_REQUESTS = 100值为100,并发设置成了为100. 降低日志级别 ...

  4. MySQL执行外部sql脚本文件命令是报错:unknown command

    使用source导入外部sql文件: mysql> source F:\php\bookorama.sql; -------------- source F: -------------- ER ...

  5. html页面加载顺序

    页面总是从上往下执行 CSS为什么要放在头部 1.CSS可以和html一起同时进行解析和渲染 2.如果你把CSS放到body后面,不但没有跟html一起进行加载渲染,还要花费额外时间去加载CSS,这样 ...

  6. poj3683 2-SAT 同上一道

    Priest John's Busiest Day Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 10151   Accep ...

  7. 21-8 数据检索2 top和distinct

    --distinct关键字,根据已经查询出的结果然后去除重复 select distinct * from TblStudent --Top(一般会配合order by一起使用) ---------- ...

  8. c# 优化代码的一些规则——优先隐式类型[一]

    前言 说到底就是优先使用var,这个关键字,在c# 3.0中出现了. 首先要确认几点,一个就是var 是静态变量,而不是动态变量,也就是说使用var 你是不必去担心性能问题得, 百度百科: 1)静态存 ...

  9. HashMap集合嵌套集合方法四种

    Map<String, HashMap<Person, String>> m=new HashMap<String, HashMap<Person, String& ...

  10. 第一章-初识AngularJS

    完全使用javascript编写的客户端技术.同其他历史悠久的Web技术配合使用,使Web应用开发比以往更简单,更快捷. Angularjs主要用于构建单页面Web应该.它通过增加开发人员和常见Web ...