## 1. 前言前端
重構老代碼中遇到了很多相似下面這種寫法:java
public void attend(String value) { if ("0".equals(value)) { //todo } else if ("1".equals(value)) { //todo } else { //todo } }
腦袋疼!從 Java 語法上無懈可擊,可是從業務上卻讓人沒法理解其中 0
和 1
的含義它們統稱爲魔法值 。 對於上面的代碼咱們每每須要經過上下文推斷出來邏輯,若是是很是複雜的業務或者10年前的代碼那就更慘了,搞很差文檔也沒有。爲了可讀性,因此咱們要儘可能避免出現魔法值。今天就來說幾種避免魔法值的操做。函數
通常魔法值都是不常常變更的。對於魔法值的處理要結合業務和做用域。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
表明的是性別(固然須要配合你良好的變量命名習慣)。設計
既然咱們使用了靜態常量那麼咱們能夠將魔法值封裝入接口也是能夠的。code
public interface Gender { String FEMALE = "0"; String MALE = "1"; }
可是接口的意義在於提供抽象的功能而不是存儲一些常量值,顯然違背了接口設計的初衷。因此jdk1.5引入了枚舉類型 enum
。接口
public enum GenderEnum { FEMALE, MALE }
不少狀況這種寫法就夠用了,你能夠經過 GenderEnum.MALE.ordinal()
獲取對應枚舉的數字序號,也能夠經過GenderEnum.MALE.name()
獲取對應枚舉的字符串名稱。他們大多數狀況下均可以用來進行一些邏輯標識。可是知足不了咱們上面最初的設計,咱們須要來改造一下枚舉類的構造函數。ip
public enum GenderEnum { FEMALE("0"), MALE("1"); private final String value; GenderEnum(String value) { this.value = value; } public String value() { return this.value; } }
這樣改寫以後咱們就能經過 value()
方法拿到具體的值了。作用域
咱們給本身再增長點需求,以達到你的枚舉更加友好的可讀性。
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 獲取更多資訊