使用枚举与布尔值?

发布于 2024-10-05 06:45:18 字数 439 浏览 3 评论 0原文

这最初看起来可能很通用,但事实上,我实际上正在做出我需要使用的决定。

我目前正在处理的工作涉及就业申请,其中需要在某些时候标记为活动非活动。提交申请后,它将默认为有效。由于某些原因,它稍后可能会被设置为非活动。它只能是其中之一,并且永远不会null(以防万一这会改变任何内容)。

我将其与 Java + Hibernate + PostgresSQL 一起使用,以防这也产生任何影响。我的第一直觉是使用 Boolean 作为我的解决方案,以便它真正充当标志,但我的同事建议使用 enumsints > 更多的是一种地位而不是一个旗帜。

我已经使用上述所有解决方案解决了此类问题,并且它们对彼此来说似乎都有些透明。

有没有一种方法更适合这种情况?

This may initially seem generic, but in fact, I am actually making the decision on which I need to use.

What I am currently working on involves Employment Applications, those in which will need to be marked at some point Active or Inactive. When an application is submitted, it will default to Active. For certain reasons, it might later be set to Inactive. It can only be one of these and never null(In case this changes anything).

I am using this with Java + Hibernate + PostgresSQL, in case this also makes any difference. My first instinct is to use Boolean as my solution so that it truly acts as a flag, but I have coworkers who have suggested using enums or ints as more of a status rather then a flag.

I have solved problems such as this using all of the above solutions, and they all seem somewhat transparent to eachother.

Is there one way that is better for this situation?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

揽清风入怀 2024-10-12 06:45:18

即使忽略将来添加更多状态类型的可能性(这无疑是枚举的一个很好的论据),我认为枚举绝对是正确的方法。您不是在建模布尔条件,而是在建模应用程序的状态。想一想:应用程序的状态不是truefalse,而是活动或非活动!状态enum将以最自然的方式表示这一点。

您还可以通过使用枚举获得许多内置优势,例如将每个状态的文本描述直接与其绑定,因此您不必执行类似“

String text = application.isActive() ? "Active" : "Inactive";

您可以这样做”

String text = application.getStatus().toString();

的操作此外,您可以直接绑定特定行为使用每个枚举实现不同的抽象方法到每个状态,将特定数据与每个状态相关联,等等。

您还可以轻松地允许基于状态的布尔 isActive 检查...您不能如果您只存储一个布尔值,则可以轻松地以相反的方式做到这一点。

public boolean isActive() {
  return status == Status.ACTIVE;
}

事实上 null 不应该是一个有效的状态是无关紧要的......只需确保存储状态的任何类(例如,您的 EmploymentApplication 类或其他类)抛出如果有人尝试对其设置 null 状态,则会出现 NullPointerException

Even ignoring the possibility of adding more status types in the future (which is certainly one good argument for an enum), I think an enum is absolutely the right way to go. You are not modelling a boolean condition, you are modelling the status of an application. Think about it: the application's status is not true or false, it's active or inactive! A status enum will represent this in the most natural way.

You also get a lot of built in advantages from using an enum, such as having a text description of each status tied directly to it, so you don't have to do things like

String text = application.isActive() ? "Active" : "Inactive";

You can just do

String text = application.getStatus().toString();

Additionally, you can tie specific behavior directly to each status with abstract methods that each enum implements differently, associate specific data with each status, etc.

You can also easily allow a boolean isActive check that is based on the status... you can't easily do that the other way around if you just store a boolean.

public boolean isActive() {
  return status == Status.ACTIVE;
}

And the fact that null shouldn't be a valid status is irrelevant... just ensure that any classes that store the status (say, your EmploymentApplication class or whatever) throw a NullPointerException if anyone tries to set a null status on it.

苏大泽ㄣ 2024-10-12 06:45:18

这完全取决于您的要求/规格。如果您只想将状态记录为活动或非活动,最好的方法是使用boolean

但如果将来,您将拥有诸如

  • ACTIVE
  • INACTIVE
  • SUSPENDED
  • BLOCKED

Enums 之类的状态,那么 Enums 非常适合您。就您而言,目前,布尔值就足够了。不要过早尝试过于复杂的事情,你会失去设计和设计的重点。您的系统的开发。

It totally depends on your requirement/specification. If you only want to record the status as active or inactive, the best way is to use boolean.

But if in the future, you will have a status such as,

  • ACTIVE
  • INACTIVE
  • SUSPENDED
  • BLOCKED

Enums is perfect for you. In your case, for now, a boolean is sufficient. Don't try overcomplicate things too early, you'll lose focus in your design & development of your system.

欲拥i 2024-10-12 06:45:18

绝对不要使用 int。使用枚举是面向未来的;您必须自己决定什么更具可读性,以及 YAGNI 是否适用。请注意,booleanBoolean 不同; Boolean 是一个类名,因此,Boolean 类型的变量可以为 null;而 boolean 是一个原语。

Definitely don't use an int. Using an enum is future-proofing; you have to decide for yourself what's more readable, and whether YAGNI applies. Be aware that boolean is not the same thing as Boolean; Boolean is a class name, and as such, variables of type Boolean can be null; whereas boolean is a primitive.

小兔几 2024-10-12 06:45:18

布尔值在商业中很少见 根据我为商业

构建自定义应用程序的经验,诸如“女性/男性”或“开/关”之类的明显二元性几乎总是会演变或变形​​为多个值。

  • “女性/男性”变成“未知/女性/男性”
  • “开/关”变成“开/热身/冷却/关”
  • “未完成/完成”变成“未完成/正在处理/已完成”

业务规则往往无法及早完全了解 -上,或随着时间的推移而改变。

和我的许多同事一样,我经历了惨痛的教训才知道永远不要将此类值定义为布尔值。稍后从布尔值更改为多个值是相当昂贵且有风险的。

Java 枚举

与布尔值相比,枚举还有其他优点。

Java 枚举非常灵活且易于使用。强大

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

虽然布尔值以字符串形式显示为 truefalse,但在枚举中您可以覆盖 toString生成更具信息性的值,例如 app-status-inactive

这些值在记录、跟踪或调试时可能非常有用。

Booleans are rare in business & industry

In my experience building custom apps for business, an apparent duality such as "Female/Male" or "On/Off" nearly always evolve or morph into multiple values.

  • "Female/Male" becomes "Unknown/Female/Male"
  • "On/Off" becomes "On/WarmingUp/CoolingDown/Off"
  • "Incomplete/Completed" becomes "Incomplete/Processing/Completed"

Business rules are often not fully known early-on, or change over time.

Like many of my colleagues, I learned the hard way to never define such values as booleans. Changing from boolean to multiple values later is quite expensive and risky.

Java enums

Enums have other benefits over a boolean.

Java enums are flexible & powerful

The Enum facility in Java is much more flexible, powerful, and useful than enums in most other languages. See Oracle Tutorial.

Within your enum definition you can house representations of the values for presentation to the user and for storage in databases or files. This makes a handy one-stop-shop for a programmer to read all about this enum and how it used in your app.

Here is a complete example. This one class shows what values we use in the user-interface and what values we persist.

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() ; }

}

Translating persisted values back to enum object

Notice the static method that can return a Status object matching a persisted value retrieved from a database:

Status s = Status.ofCodeName( myResultSet.getString( "code" ) ) ;

Flexible sets/maps

In Java, enums have their own implementation of Set and Map that are highly optimized both in terms of very little memory used and very fast execution.

Set< Status > auditApprovedStatuses = EnumSet.of( Status.ACTIVE , Status.INACTIVE ) ;  
Set< Status > auditAlertStatuses = EnumSet.of( Status.UNKNOWN ) ;

…

if( auditAlertStatuses.contains( application.getStatus() ) ) {
    this.alertAuditor( application ) ;
}

Notice how easy to update these set definitions if your definition of application-status changes.

Informative toString value

Whereas a boolean appears as true or false as a string, in your enum you can override toString to generate a much more informative value such as app-status-inactive.

Such values may be quite useful when logging, tracing, or debugging.

后知后觉 2024-10-12 06:45:18

难道两者都不能做吗?

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?

Is it not possible to do both?

enum Status {
    ACTIVE(true), INACTIVE(false);
    private final boolean value;
    Status(boolean value) {
        this.value = value;
    }
    boolean getValue() {
        return this.value;
    }
}

Does this not get you the best of both worlds? It lets you use a boolean with the names ACTIVE and INACTIVE, rather than true and false?

吹泡泡o 2024-10-12 06:45:18

如果真/假是唯一的可能性,则布尔值比枚举更有意义(开销更少)。建议:使用布尔类而不是布尔原语,这样您就可以检测“未知/未定义”状态以及真/假。

If true/false are the only possibilities, boolean makes more sense than enum (less overhead). Recommendation: Use the Boolean class instead of the boolean primitive, so you can detect the "unknown/undefined" state as well as true/false.

无远思近则忧 2024-10-12 06:45:18

如果您可能需要除“活动”和“非活动”之外的更多状态,那么您会想要使用 enum 或 int 状态标志?这使得您的代码对于未来的状态更加灵活。

If you might ever have a need for more statuses other than Active and Inactive then you would want to use and enum or int status flag? That makes your code more flexible for future statuses.

迷途知返 2024-10-12 06:45:18

在你的情况下,有一个布尔值就足够了。由于要求是“IsActive”,并且立即答案可以是 true 或 false。有一个枚举是可以的,但在我看来,布尔值是合适的

In your case having a boolean value should suffice. Since the requirement is 'IsActive' and the immediate answer can be either true or false. Having an enum is ok but IMO, a boolean is right suited

秋千易 2024-10-12 06:45:18

我认为使用 Enum 而不是 Boolean 更好。

Joshua Bloch (2008):

  • Effective Java: Still effective After AllThese Years,第二版,第 6 章:枚举和注释

列出了双元素枚举相对于布尔值的以下优点:

  • 代码更易于阅读
  • 代码更容易编写(尤其是使用 IDE)
  • 更少需要查阅文档
  • 错误概率
  • 更小 更利于 API 的发展

源自幻灯片 (PDF) - 可能受到限制:
https://www.cs.umd.edu/ class/fall2009/cmsc132H/slides/still- effective.pdf

或者存档但可在以下位置访问:
https://web.archive.org/web/20120404070225/http://www.cs.umd.edu/class/fall2009/cmsc132H/slides/still- effective.pdf

I think it is better to use Enum instead of Boolean.

The book

  • Joshua Bloch (2008): Effective Java: Still Effective After All These Years, Second Edition, Chapter 6: Enums and Annotations

lists following advantages of two-element enums over booleans:

  • Code is easier to read
  • Code is easier to write (especially with IDE)
  • Less need to consult documentation
  • Smaller probability of error
  • Much better for API evolution

Sourced from slides (PDF) - might be restricted:
https://www.cs.umd.edu/class/fall2009/cmsc132H/slides/still-effective.pdf

alternatively archived but accessible at:
https://web.archive.org/web/20120404070225/http://www.cs.umd.edu/class/fall2009/cmsc132H/slides/still-effective.pdf

带刺的爱情 2024-10-12 06:45:18

我更喜欢枚举器,因为我与远程团队合作理解他们的代码,然后在深夜编写包含样板代码的测试用例,我相信使用enum比使用enum要好得多 boolean 不仅有助于良好的设计,还可以减少思考负担并提高可读性。

I prefer enumerators as I collaborate with remote team comprehending their code and then writing test cases at the dead of night containing boilerplate code I believe use of enum are way and way better than boolean not only it aids in good designs but also reduces cogitative load and increases readability.

有深☉意 2024-10-12 06:45:18

如果在 isX/hasXisY/hasY 之间为布尔属性进行选择似乎是任意的,请使用枚举。

在您的情况下,布尔值应该足够了(最好是 isActive 而不是 isInactive)。

If it seems arbitrary to choose between isX/hasX and isY/hasY for your boolean property, use an enum.

In your case a boolean should suffice (preferably isActive over isInactive).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文