重构老代码中遇到了很多相似下面这种写法:前端
public void attend(String value) { if ("0".equals(value)) { //todo } else if ("1".equals(value)) { //todo } else { //todo } }
脑袋疼!从 Java 语法上无懈可击,可是从业务上却让人没法理解其中 0
和 1
的含义它们统称为魔法值 。 对于上面的代码咱们每每须要经过上下文推断出来逻辑,若是是很是复杂的业务或者10年前的代码那就更惨了,搞很差文档也没有。为了可读性,因此咱们要尽可能避免出现魔法值。今天就来说几种避免魔法值的操做。java
通常魔法值都是不常常变更的。对于魔法值的处理要结合业务和做用域。函数
若是该值的做用域在一个类中或者同一个包下,通常可使用静态常量来解决。this
private static final String FEMALE = "0"; private static final String MALE = "1"; public void attend(String value) { if (FEMALE.equals(value)) { //todo } else if (MALE.equals(value)) { //todo } else { //todo } }
这样是否是清晰了许多,原来 0
和 1
表明的是性别(固然须要配合你良好的变量命名习惯)。编码
既然咱们使用了静态常量那么咱们能够将魔法值封装入接口也是能够的。设计
public interface Gender { String FEMALE = "0"; String MALE = "1"; }
可是接口的意义在于提供抽象的功能而不是存储一些常量值,显然违背了接口设计的初衷。因此jdk1.5引入了枚举类型 enum
。code
public enum GenderEnum { FEMALE, MALE }
不少状况这种写法就够用了,你能够经过 GenderEnum.MALE.ordinal()
获取对应枚举的数字序号,也能够经过GenderEnum.MALE.name()
获取对应枚举的字符串名称。他们大多数状况下均可以用来进行一些逻辑标识。可是知足不了咱们上面最初的设计,咱们须要来改造一下枚举类的构造函数。接口
public enum GenderEnum { FEMALE("0"), MALE("1"); private final String value; GenderEnum(String value) { this.value = value; } public String value() { return this.value; } }
这样改写以后咱们就能经过 value()
方法拿到具体的值了。ip
咱们给本身再增长点需求,以达到你的枚举更加友好的可读性。作用域
public enum GenderEnum { UNKNOWN("-1", "未知"), FEMALE("0", "女性"), MALE("1", "男性"); private final String value; private final String description; GenderEnum(String value, String description) { this.value = value; this.description = description; } public String value() { return this.value; } public String description() { return this.description; } }
description
值不但能够帮助咱们知道该枚举的实际表明意义,甚至能够做为一种说明返回给前端业务。
小贴士:枚举尽可能不要使用中文声明,如 FEMALE 直接声明为 女性。另外枚举是单例的,所以没法使用clone和反序列化。
今天咱们了解了如何优雅处理编码中的魔法值,特别是枚举方案。但愿对你有用。
关注公众号:Felordcn 获取更多资讯