布尔值在商业和工业中很少见
根据我为企业构建自定义应用程序的经验,“女性/男性”或“开/关”等明显的二元性几乎总是会演变或演变为多个值。
- “女/男”变为“未知/女/男”
- “开/关”变为“开/暖机/冷却/关”
- “未完成/已完成”变为“未完成/处理中/已完成”
业务规则通常在早期并不完全了解,或者随着时间的推移而变化。
像我的许多同事一样,我学会了永远不要将此类值定义为布尔值的艰难方法。以后从布尔值更改为多个值是非常昂贵和冒险的。
Java 枚举
枚举比布尔值有其他好处。
Java 枚举灵活而强大
Java 中的Enum 工具比大多数其他语言中的枚举更加灵活、强大和有用。见Oracle Tutorial。
在您的枚举定义中,您可以将值的表示形式提供给用户并存储在数据库或文件中。这为程序员提供了一个方便的一站式商店来阅读有关此枚举的所有信息以及它在您的应用中的使用方式。
这是一个完整的例子。这一类显示了我们在用户界面中使用的值以及我们保留的值。
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。
这些值在记录、跟踪或调试时可能非常有用。