java 枚举 菜鸟_2个菜鸟Java常量和枚举陷阱
java 枚舉 菜鳥
在對Java和Groovy代碼進行的各種代碼審查中,我經常看到魔術數字和其他隨機字符串散落在整個代碼庫中。
例如,下面的(Groovy)代碼段中的4.2是一個神奇的數字:
if (swashbuckle >= 4.2) {... }4.2是什么意思?
我的建議是將一個數字提取為一個常數,并為其賦予一個有意義的意圖顯示名稱,以便我們所有人都可以繼續理解我們的代碼。
重構成
if (swashbuckle >= MAX_ALLOWED_CAPACITY) {... }即使是初學者,也可以理解The Constant的值,并開始將各地的值提取為常量。 當我談論枚舉時,編寫可讀代碼的可能性更大,但是經驗不足的開發人員很快就會陷入以下陷阱。
陷阱#1全球über-Constants文件
應盡可能避免使用全局常量文件,例如
class Constants {private static final String PEACH_FLAME = "PFL"private static final int MAX_TOOGIT = 17private static final int MIN_TOOGIT = 8private static final String USER_NAME_AGE_PROPERTY = "age"private static final String USER_NAME_FLOPPY_PROPERTY = "floppy"private static final int CUSTOM_HYSLERIA_DONE = -99private static final List<String> WOBBA_RANGE = ['BZ, 'FLL', 'BZZ']// dozens of other constants...引用StackOverflow總結得很好 :
我強烈建議不要使用單個常量類。 當時這似乎是個好主意,但是當開發人員拒絕記錄常量并且該類增長到包含多達500個完全不相關的常量(與應用程序的完全不同的方面)時,這通常會變成完全不可讀的常量文件。 代替:
- 如果可以訪問Java 5+,請使用枚舉為應用程序區域定義特定的常量。 對于這些常量,應用程序區域的所有部分都應引用枚舉,而不是常量。 您可以聲明類似于聲明類的枚舉。 枚舉也許是Java 5+的最(也是唯一的)有用的功能。
- 如果您的常量僅對特定類或其子類之一有效,則將其聲明為protected或public,然后將其放在層次結構中的頂級類上。 這樣,子類可以訪問這些常量值(如果其他類通過公共訪問它們,則這些常量不僅僅對特定的類有效……這意味著使用該常量的外部類可能與包含該常量的類緊密耦合。常數)
- 如果您有一個定義了行為的接口,但是返回值或參數值應該特別,那么在該接口上定義常量是完全可以接受的,以便其他實現者可以訪問它們。 但是,請避免創建僅用于保存常量的接口:它可能與僅為保存常量而創建的類一樣糟糕。
單個類(例如我們上面的Constants示例)很快就變成了一切 。 新秀開發人員認為,他通過將魔術數字和魔術字符串提取為常量來遵循良好的(代碼審查)建議,但是團隊很快就承擔了新的維護負擔。
如果你發現自己(或你的團隊)這樣做,請把負責任的車主如用戶相關的常數常量在UserService在和wobba相關常量WobbaConverter -不管它是什么
還請閱讀上面注釋中有關枚舉的部分,因為常量并不是鎮上唯一的孩子。 有時我的建議是……
首選枚舉
如果您的常數可以很好地建模為枚舉,請考慮枚舉結構。 枚舉比簡單的常量更具通用性 ; 它們是類,可以包含屬性和方法。
在負責任的父類中。
更喜歡
class Person {enum Gender { M, F }String nameGender gender }過度
class Person {static final String GENDER_MALE = 'M'static final String GENDER_FEMALE = 'F'String nameString gender }或作為使用它的班級附近的一個單獨的班級 (如果它變大)。 具有功能名稱的enum類的一個很好的例子是例如一些相關的(技術)數據
/*** Represents medicine domain codes.*/ public enum MedicineCode {/** Diagnosis e.g. "Muscle damage". */DIAGNOSIS("X357"),/** Units in medicinal context e.g. "cc/ml". */MEDICINE_UNIT("X523"),/*** Cause codes for diagnosis = 'Masitis' e.g. "E.coli (ECO)".*/CAUSE_CODE("X536"),/** TreatmentType e.g. "Antibiotics". */INTERVAL_TYPE("X520"), MedicineCode(String code) {this.code = code;}private final String code;public String code() {return code;}/*** Find a {@link MedicineCode} by given String code.** @param code The code e.g. "X261"* @return found medicine code, or null*/public static MedicineCode findByCode(String code) {values().find { it.code() == code }}@Overridepublic String toString() {return name() + "(" + code() + ")"} }每當需要表示一組固定的常量時,都應使用枚舉類型。 因此,新秀開發人員認為他通過將內容提取到枚舉,封裝技術數據,使用功能名稱等方式來遵循良好的(代碼審查)建議,但通常會陷入
陷阱#2定義枚舉,但未正確使用它們
因此,如果您最初具有以下方法和調用:
Medicine findMedicineForDomainCode(String code)// which you call like: String intervalTypeCode = "X520" findMedicineForDomainCode(intervalTypeCode)并且您可能會引入像MedicineCode這樣的枚舉(請參見上文),將所有這些特定于域的技術(例如數據庫“ X…”)代碼(例如“ X520”)封裝在一起,然后不要這樣做:
Medicine findMedicineForDomainCode(String domainCode)// which one keeps calling like: String intervalTypeCode = MedicineCode.findByCode("X520") findMedicineForDomainCode(intervalTypeCode)我見過像這樣的團隊。 是的,有一個帶有值的枚舉類型,但是團隊在整個代碼中并不十分了解如何處理它們。
第一步是直接引用枚舉 。 某些菜鳥開發人員通常最初已經理解了這一點,這取決于他們是否遵循Oracle Java Enum Types教程或類似內容,但通常會導致如下所示:
Medicine findMedicineForDomainCode(String code)// which one calls like: String intervalTypeCode = INTERVAL_TYPE.code() // WRONG! still using Strings here findMedicineForDomainCode(intervalTypeCode)有了枚舉意味著我們現在可以鍵入所有內容,包括返回類型和方法參數 。
只是將枚舉用作容納字符串的容器并不是我們這樣做的原因:為了獲得更好的類型安全性和可讀性,您應該重構代碼中的所有內容,以便將域代碼用作MedicineCode枚舉的字符串類。
更好:
// first refactor method parameter from String to MedicineCode Medicine findMedicineForDomainCode(MedicineCode code)// now just pass an enum value findMedicineForDomainCode(INTERVAL_TYPE)然后,直到那時,在最后一個可能的時刻,您需要實際封裝的String代碼(“ X520”)–可以從枚舉值中提取它。
希望這有助于定義常量和使用枚舉。 我無法涵蓋使用適當設計的枚舉類型可能具有的所有“有效”用法和OO優勢的所有其他情況,但是希望本文能夠防止Java新手陷入所描述的陷阱。
翻譯自: https://www.javacodegeeks.com/2016/04/2-rookie-java-constants-enums-pitfalls.html
java 枚舉 菜鳥
總結
以上是生活随笔為你收集整理的java 枚举 菜鸟_2个菜鸟Java常量和枚举陷阱的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 群友斗地主能在电脑上玩(欢乐斗地主能在电
- 下一篇: spring async_Spring