[英]Using enum vs Boolean?
這最初可能看起來很籠統,但實際上,我實際上正在做出我需要使用的決定。
我目前正在處理的工作涉及就業申請,其中需要在某些時候標記為Active或Inactive 。 提交應用程序時,它將默認為Active 。 由於某些原因,它稍后可能會設置為Inactive 。 它只能是其中之一,而不能是 null (如果這會改變任何事情)。
我將它與Java + Hibernate + PostgresSQL一起使用,以防萬一這也有任何區別。 我的第一直覺是使用Boolean作為我的解決方案,以便它真正充當標志,但我有同事建議使用枚舉或整數作為一種狀態而不是標志。
我已經使用上述所有解決方案解決了諸如此類的問題,而且它們似乎對彼此都有些透明。
有沒有一種更適合這種情況的方法?
這完全取決於您的要求/規格。 如果您只想將狀態記錄為活動或非活動,最好的方法是使用boolean
。
但是,如果將來,您將擁有諸如,
枚舉非常適合您。 就您而言,目前,布爾值就足夠了。 不要過早嘗試使事情變得過於復雜,否則您將失去對系統設計和開發的關注。
即使忽略將來添加更多狀態類型的可能性(這對於enum
來說當然是一個很好的論據),我認為enum
絕對是正確的方法。 您不是在為布爾條件建模,而是在為應用程序的狀態建模。 想一想:應用程序的狀態不是true或false ,它是活動的還是非活動的! 狀態enum
將以最自然的方式表示這一點。
您還可以通過使用枚舉獲得許多內置優勢,例如將每個狀態的文本描述直接關聯到它,因此您不必做類似的事情
String text = application.isActive() ? "Active" : "Inactive";
你可以做
String text = application.getStatus().toString();
此外,您可以使用每個枚舉以不同方式實現的抽象方法將特定行為直接綁定到每個狀態,將特定數據與每個狀態相關聯,等等。
您還可以輕松地允許基於狀態的 boolean isActive
檢查...如果您只存儲一個boolean
,則不能輕松地反過來這樣做。
public boolean isActive() {
return status == Status.ACTIVE;
}
而且null
不應該是有效狀態這一事實是無關緊要的……只要確保任何存儲狀態的類(例如,您的EmploymentApplication
類或其他類)在有人試圖在其上設置null
狀態時拋出NullPointerException
。
絕對不要使用int。 使用枚舉是面向未來的; 你必須自己決定什么更具可讀性,以及YAGNI是否適用。 請注意, boolean
與Boolean
; Boolean
是一個類名,因此, Boolean
類型的變量可以為 null; 而boolean
是一個原語。
根據我為企業構建自定義應用程序的經驗,諸如“女性/男性”或“開/關”之類的明顯二元性幾乎總是會演變或演變為多個值。
業務規則通常在早期並不完全了解,或者隨着時間的推移而變化。
像我的許多同事一樣,我學會了從不將此類值定義為布爾值的艱難方法。 稍后從布爾值更改為多個值非常昂貴且有風險。
枚舉比布爾值還有其他好處。
Java 中的Enum
工具比大多數其他語言中的枚舉更加靈活、強大和有用。 請參閱Oracle 教程。
在您的枚舉定義中,您可以容納值的表示形式,以便向用戶展示和存儲在數據庫或文件中。 這為程序員提供了一個方便的一站式商店,可以閱讀有關此枚舉的所有信息以及它在您的應用程序中的使用方式。
這是一個完整的例子。 這一類顯示了我們在用戶界面中使用的值以及我們保留的值。
package com.basilbourque.example;
public enum Status {
ACTIVE( "Active" , "active" ),
INACTIVE( "Inactive" , "inactive" ),
UNKNOWN( "Unknown" , "unknown" );
private String displayName, codeName;
Status ( String displayName , String codeName ) {
this.displayName = displayName;
this.codeName = codeName;
}
public String getDisplayName () { return this.displayName; } // Or even add a `Locale` argument to support localization.
public String getCodeName () { return this.codeName; }
// To find a `Status` enum object matching input retrieved from a database.
static public Status ofCodeName ( String codeName ) {
// Loop each of the enum objects to find a match.
for ( Status s : Status.values() ) {
if ( s.getCodeName().equals( codeName ) ) { return s; }
}
throw new IllegalArgumentException( "No such Status code name as: " + codeName );
}
@Override
public String toString() { return "app-status-" + this.getCodeName() ; }
}
請注意可以返回與從數據庫中檢索到的持久值匹配的Status
對象的靜態方法:
Status s = Status.ofCodeName( myResultSet.getString( "code" ) ) ;
在 Java 中,枚舉有自己的Set
和Map
實現,它們在使用的內存很少和執行速度非常快方面都進行了高度優化。
Set< Status > auditApprovedStatuses = EnumSet.of( Status.ACTIVE , Status.INACTIVE ) ;
Set< Status > auditAlertStatuses = EnumSet.of( Status.UNKNOWN ) ;
…
if( auditAlertStatuses.contains( application.getStatus() ) ) {
this.alertAuditor( application ) ;
}
請注意,如果您的應用程序狀態定義發生變化,更新這些集合定義是多么容易。
toString
值雖然布爾值顯示為true
或false
作為字符串,但在您的枚舉中,您可以覆蓋toString
以生成更多信息值,例如app-status-inactive
。
這些值在記錄、跟蹤或調試時可能非常有用。
兩者都不能做嗎?
enum Status {
ACTIVE(true), INACTIVE(false);
private final boolean value;
Status(boolean value) {
this.value = value;
}
boolean getValue() {
return this.value;
}
}
這難道不是讓你兩全其美嗎? 它允許您使用名稱為 ACTIVE 和 INACTIVE 的布爾值,而不是 true 和 false?
如果真/假是唯一的可能性,布爾值比枚舉更有意義(更少的開銷)。 建議:使用 Boolean 類而不是 boolean 原語,這樣您就可以檢測“未知/未定義”狀態以及真/假。
如果您可能需要除 Active 和 Inactive 之外的更多狀態,那么您會想要使用 enum 或 int 狀態標志嗎? 這使您的代碼對於未來的狀態更加靈活。
在你的情況下,有一個布爾值就足夠了。 由於要求是“IsActive”,因此立即回答可以為真,也可以為假。 有一個枚舉是可以的,但 IMO,一個布爾值是正確的
我認為最好使用 Enum 而不是 Boolean。 在 Effective java 中,它更喜歡二元素枚舉而不是布爾值。 它還提出了它的以下優點。 代碼更容易閱讀 • 代碼更容易閱讀 • 代碼更容易編寫(尤其是使用 IDE) • 不需要查閱文檔 • 出錯概率更小 • 更適合 API 演進
請參閱以下鏈接以獲取更多詳細信息。 https://www.cs.umd.edu/class/fall2009/cmsc132H/slides/still-effective.pdf
我更喜歡枚舉器,因為我與遠程團隊合作理解他們的代碼,然后在深夜編寫包含樣板代碼的測試用例我相信enum
使用方式enum
boolean
更好,不僅有助於良好的設計,而且還減少了認知負荷和增加可讀性。
如果您的 boolean 屬性在isX
/ hasX
和isY
/ hasY
之間進行選擇似乎是任意的,請使用枚舉。
在您的情況下, boolean 應該就足夠了(最好是isActive
而不是isInactive
)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.