Использование enum vs Boolean? - PullRequest
13 голосов
/ 02 декабря 2010

Поначалу это может показаться общим, но на самом деле, я на самом деле принимаю решение, которое мне нужно использовать.

В настоящее время я работаю над приложениями для трудоустройства, в которых нужно будет отметитьв какой-то момент Активно или Неактивно .Когда заявка отправлена, она по умолчанию будет Активная .По определенным причинам позже он может быть установлен на Неактивно .Это может быть только один из них и никогда null (в случае, если это что-то изменит).

Я использую это с Java + Hibernate + PostgresSQL , если этотакже имеет значение.Мой первый инстинкт - использовать Boolean в качестве моего решения, чтобы оно действительно действовало как флаг, но у меня есть коллеги, которые предложили использовать enums или ints как большестатуса, а не флаг.

Я решил такие проблемы, используя все вышеперечисленные решения, и все они кажутся друг другу несколько прозрачными.

Есть ли один способ, который лучше для этой ситуации?

Ответы [ 9 ]

12 голосов
/ 02 декабря 2010

Даже игнорируя возможность добавления новых типов состояний в будущем (что, безусловно, является хорошим аргументом для enum), я думаю, что enum - абсолютно верный путь.Вы не моделируете логическое условие, вы моделируете состояние приложения.Подумайте об этом: статус приложения не true или false , он активен или неактивен!Статус enum будет представлять это наиболее естественным образом.

Вы также получаете множество встроенных преимуществ от использования enum, например привязки текстового описания каждого статуса непосредственно к нему, так что выне нужно делать что-то вроде

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

Вы можете просто сделать

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

Кроме того, вы можете привязать определенное поведение непосредственно к каждому состоянию с помощью абстрактных методов, которые каждое перечисление реализует по-своему,связывать определенные данные с каждым статусом и т. д.

Вы также можете легко разрешить логическую isActive проверку, основанную на статусе ... вы не можете легко сделать это наоборот, если просто сохранитеa boolean.

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

И тот факт, что null не должен быть действительным статусом, не имеет значения ... просто убедитесь, что все классы, которые хранят статус (скажем, ваш EmploymentApplication класс)или что-то еще) бросьте NullPointerException, если кто-то попытается установить для него статус null.

11 голосов
/ 02 декабря 2010

Определенно не используйте int.Использование перечисления является перспективой;Вы должны решить для себя, что является более читабельным и применимо ли YAGNI Помните, что boolean - это не то же самое, что Boolean;Boolean - это имя класса, и поэтому переменные типа Boolean могут быть нулевыми;тогда как boolean является примитивом.

10 голосов
/ 02 декабря 2010

Это полностью зависит от ваших требований / спецификаций.Если вы хотите записать статус как активный или неактивный, лучше всего использовать boolean.

Но если в будущем у вас будет такой статус, как

  • ACTIVE
  • INACTIVE
  • SUSPENDED
  • BLOCKED

Enums идеально подходит для вас.В вашем случае, на данный момент, логическое значение достаточно.Не пытайтесь слишком усложнять вещи слишком рано, вы потеряете фокус при проектировании и разработке вашей системы.

3 голосов
/ 02 декабря 2010

Если вам когда-нибудь понадобится больше статусов, кроме «Активный» и «Неактивный», то вы захотите использовать и enum или int status flag? Это делает ваш код более гибким для будущих статусов.

2 голосов
/ 03 октября 2012

Разве невозможно сделать и то и другое?

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?

2 голосов
/ 02 декабря 2010

Если true / false являются единственными возможностями, логическое значение имеет больше смысла, чем enum (меньше накладных расходов). Рекомендация: используйте логический класс вместо логического примитива, чтобы вы могли обнаружить состояние «неизвестно / не определено», а также истина / ложь.

1 голос
/ 07 октября 2018

Булевы значения редко встречаются в бизнесе и промышленности

По моему опыту создания пользовательских приложений для бизнеса, очевидная двойственность, такая как «Женский / Мужской» или «Вкл. / Выкл.», Почти всегда эволюционирует или трансформируется в несколько значений.

  • «Женский / Мужской» становится «Неизвестный / Женский / Мужской»
  • «Вкл. / Выкл.» Становится «Вкл. / Прогрев / Охлаждение / Выкл.»

Бизнес-правила часто не полностью известны на раннем этапе или меняются со временем.

Как и многие мои коллеги, я научился трудному способу никогда не определять такие значения как булевы.Переход от логических значений к множественным значениям позже довольно дорог и рискован.

Перечисления Java

Перечисления имеют другие преимущества по сравнению с булевыми.

Перечисления Java являются гибкими и мощными

Возможность Enum в Java гораздо более эффективнагибкий, мощный и полезный, чем перечисления в большинстве других языков.См. Oracle Tutorial .

В вашем определении enum вы можете разместить представления значений для представления пользователю и для хранения в базах данных или файлах.Это позволяет программисту в одном окне прочитать все об этом перечислении и о том, как оно используется в вашем приложении.

Вот полный пример.Этот класс показывает, какие значения мы используем в пользовательском интерфейсе и какие значения мы сохраняем.

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.

Такие значения могут быть весьма полезны при ведении журнала, трассировки или отладки.

1 голос
/ 02 декабря 2010

В вашем случае достаточно иметь логическое значение. Поскольку требование «IsActive» и немедленный ответ может быть либо истинным, либо ложным. Наличие перечисления в порядке, но IMO, логическое значение подходит

0 голосов
/ 04 декабря 2014

Я думаю, что лучше использовать Enum вместо Boolean.В Effective java он предпочитает двухэлементные перечисления для логических значений.Он также предложил следующие преимущества.Код легче читать • Код легче читать • Код легче писать (особенно с IDE) • Меньше необходимости обращаться к документации • Меньшая вероятность ошибки • Гораздо лучше для развития API

Пожалуйста, обратитесь по ссылке нижечтобы получить больше деталей.https://www.cs.umd.edu/class/fall2009/cmsc132H/slides/still-effective.pdf

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...