这可能最初似乎是通用的,但事实上,我实际上正在做出我需要使用的决定。
我目前正在进行的工作涉及就业申请,其中需要在某些时候标记有效或无效。提交申请时,默认为有效。出于某些原因,稍后可能会将其设置为无效。它只能是其中之一,永远不会 null (如果这改变了什么)。
我在 Java + Hibernate + PostgresSQL 中使用它,以防这也有所不同。我的第一直觉是使用布尔作为我的解决方案,以便它真正作为一个标志,但我有同事建议使用枚举或整体更像是一种状态,而不是一面旗帜。
我已经使用上述所有解决方案解决了诸如此类的问题,并且它们对彼此都显得有些透明。
对于这种情况,有哪种方法更好?
答案 0 :(得分:12)
即使忽略了将来添加更多状态类型的可能性(这肯定是enum
的一个好参数),我认为enum
绝对是正确的方法。您没有建模布尔条件,您正在建模应用程序的状态。想一想:应用程序的状态不是 true 或 false ,它是活动的还是非活动的!状态enum
将以最自然的方式表示。
使用枚举还可以获得许多内置优势,例如将每个状态的文本描述直接绑定到它,因此您不必执行诸如
之类的操作String text = application.isActive() ? "Active" : "Inactive";
你可以做到
String text = application.getStatus().toString();
此外,您可以使用每个枚举实现不同的抽象方法将特定行为直接绑定到每个状态,将特定数据与每个状态相关联等。
您还可以轻松地允许基于状态的布尔isActive
检查...如果您只存储boolean
,则无法轻易做到这一点。
public boolean isActive() {
return status == Status.ACTIVE;
}
null
不应该是有效状态这一事实无关紧要......只需确保存储状态的任何类(例如,您的EmploymentApplication
类或其他类)抛出{{ 1}}如果有人试图在其上设置NullPointerException
状态。
答案 1 :(得分:11)
绝对不要使用int。使用枚举是面向未来的;你必须自己决定哪些更具可读性,以及YAGNI是否适用。请注意boolean
与Boolean
不同; Boolean
是类名,因此,Boolean
类型的变量可以为null;而boolean
是原始的。
答案 2 :(得分:10)
完全取决于您的要求/规格。如果您只想将状态记录为活动或非活动状态,最好的方法是使用boolean
。
但如果在将来,您将拥有诸如
之类的状态Enums非常适合您。在你的情况下,现在,布尔值就足够了。不要过早地尝试过度复杂化,你将失去对设计的关注。开发你的系统。
答案 3 :(得分:3)
如果您可能需要除Active和Inactive以外的更多状态,那么您是否希望使用和枚举或int状态标志?这使您的代码在未来的状态中更加灵活。
答案 4 :(得分:2)
如果true / false是唯一的可能性,boolean比enum更有意义(更少的开销)。建议:使用布尔类而不是布尔基元,这样就可以检测“未知/未定义”状态以及真/假。
答案 5 :(得分:2)
这两种情况都不可能吗?
enum Status {
ACTIVATE(true), INACTIVE(false);
private final boolean value;
Status(boolean value) {
this.value = value;
}
boolean getValue() {
return this.value;
}
}
这不能让你两全其美吗?它允许你使用名称为ACTIVE和INACTIVE的布尔值,而不是true和false?
答案 6 :(得分:1)
在你的情况下,有一个布尔值就足够了。由于要求是'IsActive'并且直接答案可以是真或假。有一个枚举是可以的,但IMO,布尔值是合适的
答案 7 :(得分:1)
根据我为企业构建自定义应用程序的经验,诸如“女性/男性”或“开/关”之类的二元性几乎总是演变或演变为多个价值。
业务规则通常不会在早期就被完全了解,或者随着时间的变化而变化。
就像我的许多同事一样,我学会了从不定义布尔值的艰难方法。稍后从布尔值更改为多个值是非常昂贵且冒险的。
枚举与布尔值相比还有其他好处。
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
。
在记录,跟踪或调试时,这些值可能非常有用。
答案 8 :(得分:0)
我认为最好使用Enum而不是Boolean。在Effective java中,它更喜欢使用双元素枚举来实现布尔值。它还提出了以下优点。 代码更容易阅读 •代码更易于阅读 •代码更容易编写(特别是使用IDE) •不需要查阅文档 •错误概率较小 •更好的API演变
请参阅以下链接以获取更多详细信息。 https://www.cs.umd.edu/class/fall2009/cmsc132H/slides/still-effective.pdf
答案 9 :(得分:0)
我更喜欢枚举器,因为我与远程团队合作理解他们的代码,然后在深夜编写包含样板代码的测试用例,我相信使用 <!DOCTYPE html>
<html>
<head>
<title>Select</title>
<!-- Compiled and minified CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.3/css/materialize.min.css">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<!--Let browser know website is optimized for mobile-->
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
</head>
<body class="row">
<!-- your code start -->
<div class="input-field col s6 m6 l6">
<!-- Dropdown Trigger -->
<a class='dropdown-button btn' href='#' data-activates='dropdown1'>Click Me</a>
<!-- Dropdown Structure -->
<ul id="dropdown1" class="dropdown-content">
<li><a href="#">one</a></li>
<li><a href="#">two</a></li>
<li><a href="#">three</a></li>
<li><a href="#!"><i class="material-icons">arrow_drop_down</i>Menu</a></li>
</ul>
</div>
<!-- your code end -->
<!--Import jQuery before materialize.js-->
<script type="text/javascript" src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<!-- Compiled and minified JavaScript -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.3/js/materialize.min.js"></script>
<!-- Below code will make your modal open on document ready: -->
<script>
$(document).ready(function() {
$('.dropdown-button').dropdown('open');
});
</script>
</body>
</html>
会比更好 enum
不仅有助于良好的设计,而且还减少了交际负担并提高了可读性。