Использование enum'ов
От: Airat Burganov Россия http://www.burganov.com
Дата: 15.11.05 08:28
Оценка:
В большинстве случаев перечисления используются для показа состояния или типа объекта, например класс Thread.State служит для этого. Здесь используются вложенные классы, потому что вне связи с конкретным классом Thread перечисление State значения не имеет. Но в таком случае использование становится неудобным — приходится писать код вроде:
if (state == Thread.State.NEW) {
  //some code
}

Почему это неудобно? Такой код является нестандартным и во многом непонятным.

Мое мнение, что в таких случаях было бы неплохо вводить в основной класс дополнительные константы вроде
public class Thread {
   public static final NEW = State.NEW;
   // или можно так
   public static final STATE_NEW = STATE.NEW;

   //,,,,
   public enum State {
     NEW,
     //другие состояния
   }
}

К сожалению объявить State как private и совсем скрыть то, что состояние это enum не получится, так как в таком случае мы лишимся возможности сохранять состояние в переменных.
Re: Использование enum'ов
От: dshe  
Дата: 15.11.05 08:42
Оценка: +1
Здравствуйте, Airat Burganov, Вы писали:

AB>В большинстве случаев перечисления используются для показа состояния или типа объекта, например класс Thread.State служит для этого. Здесь используются вложенные классы, потому что вне связи с конкретным классом Thread перечисление State значения не имеет. Но в таком случае использование становится неудобным — приходится писать код вроде:

AB>
AB>if (state == Thread.State.NEW) {
AB>  //some code
AB>}
AB>

AB>Почему это неудобно? Такой код является нестандартным и во многом непонятным.

По-моему ты как раз привел пример использования стандартного класса java.lang.Thread.State. Куда уж стандартнее. И что конкретно в данном коде непонятно?
--
Дмитро
Re[2]: Использование enum'ов
От: Airat Burganov Россия http://www.burganov.com
Дата: 15.11.05 08:57
Оценка:
Здравствуйте, dshe, Вы писали:

D>По-моему ты как раз привел пример использования стандартного класса java.lang.Thread.State. Куда уж стандартнее. И что конкретно в данном коде непонятно?


Так писать имхо, неудобно. Возможно я поступил неверно, продемонстрировав неудобность на стандартной библиотеке...

Могу привести другой пример, более показательный, причем я сталкивался с таким кодом в практике
public class SomeClass {
  public static enum Mode {XXX,YYY}
  private final Mode mode;
  public SomeClass(Mode mode) {
    this.mode = mode;
  }

  //Действия зависят от mode
}

В таком случае для создания нового класса применяется неудобный синтаксис
someObject = new SomeClass(SomeClass.Mode.XXX)


Согласитесь, что код
  someObject = new SomeClass(SomeClass.XXX)

выглядит гораздо более привычно и понятно
Re[2]: Использование enum'ов
От: Blazkowicz Россия  
Дата: 15.11.05 09:01
Оценка:
Здравствуйте, dshe, Вы писали:

AB>>Почему это неудобно? Такой код является нестандартным и во многом непонятным.


D>По-моему ты как раз привел пример использования стандартного класса java.lang.Thread.State. Куда уж стандартнее. И что конкретно в данном коде непонятно?


Присоединяюсь к вопросам. Так же интересно какие альтернативы может предложить автор, от есть как по его мнению будет стандартно и понятно? Методы вроде isInState(thread, Thread.State.NEW)?
Re[3]: Использование enum'ов
От: Blazkowicz Россия  
Дата: 15.11.05 09:16
Оценка: +2
Здравствуйте, Airat Burganov, Вы писали:

AB>[/java]

AB>В таком случае для создания нового класса применяется неудобный синтаксис
AB>
AB>someObject = new SomeClass(SomeClass.Mode.XXX)
AB>


AB>Согласитесь, что код

AB>
AB>  someObject = new SomeClass(SomeClass.XXX)
AB>

AB>выглядит гораздо более привычно и понятно

Совсем другое дело. Теперь претензии понятны. Но опять же то что второй код "удобнее" (честно говоря странный критерий оценки), чисто субъективное мнение. Зато первый кодлет гораздо более "удобочитаем". Мы сразу понимаем что в конструтор надо передать именно режим. Также это хороший способ предотвратить путаницу констант. Например в old style Java иногда встречался подобный код:

public class SomeClass
{
     public static final int Slow = 1;
     public static final int Fast = 2;

     public static final int Dark = 1;
     public static final int Bright = 2;
}

то есть первое относится к, допустим, редиму, а второе к стилю. И здесь обязательно надо писать коментарии. А человеку использующему этот код обязательно надо прочесть эти коментарии.
В варианте же с энумами, мы сразу увидим различие SomeClass.Style.Dark, SomeStyle.Mode.Slow.
Re[3]: Использование enum'ов
От: Airat Burganov Россия http://www.burganov.com
Дата: 15.11.05 09:39
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

B>Здравствуйте, dshe, Вы писали:


B>Присоединяюсь к вопросам. Так же интересно какие альтернативы может предложить автор, от есть как по его мнению будет стандартно и понятно? Методы вроде isInState(thread, Thread.State.NEW)?

Да нет же. Мое предложение просто сводится к введению новых констант в главном классе.
public class SomeClass {
  
  public final static Mode XXX = Mode.XXX;
  public final static Mode YYY = Mode.YYY;
  
  public static enum Mode {XXX,YYY}
  private final Mode mode;
  public SomeClass(Mode mode) {
    this.mode = mode;
  }

  //Действия зависят от mode
}

И их использование. в коде
  someObject = new SomeClass(SomeClass.XXX)
Re[4]: Использование enum'ов
От: Blazkowicz Россия  
Дата: 15.11.05 09:45
Оценка: +1
Здравствуйте, Airat Burganov, Вы писали:

AB>
AB>public class SomeClass {
AB>  
AB>  public final static Mode XXX = Mode.XXX;
AB>  public final static Mode YYY = Mode.YYY;
AB>  
AB>  public static enum Mode {XXX,YYY}
AB>  private final Mode mode;
AB>  public SomeClass(Mode mode) {
AB>    this.mode = mode;
AB>  }

AB>  //Действия зависят от mode
AB>}
AB>


Идея интересная, но все равно не согласен. Читаемость кода страдает. При взгляде на

someObject = new SomeClass(SomeClass.XXX);


Не ястно что такое XXX, если константа не называется MODE_XXX, а это выглядит глупо. То есть для того тчобы разобратся надо идти в сырцы или доку классу и смотреть к чему относитя константа. В написании
someObject = new SomeClass(SomeClass.Mode.XXX);

Сразу понятно к чему относится константа без каких либо дополнительных расследований.
Re[3]: Использование enum'ов
От: vladserge Россия  
Дата: 15.11.05 09:50
Оценка:
Здравствуйте, Airat Burganov, Вы писали:

AB>В таком случае для создания нового класса применяется неудобный синтаксис

AB>
AB>someObject = new SomeClass(SomeClass.Mode.XXX)
AB>


AB>Согласитесь, что код

AB>
AB>  someObject = new SomeClass(SomeClass.XXX)
AB>

AB>выглядит гораздо более привычно и понятно

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

public class RichText 
{
    public interface Format
    {
        interface FontEffect
        {
            byte
                    UNDERSCORED = 127,
                    UNDERWAVED = 126,
                    BORDERED = 125,
                    SRIKEOUT = 124,
                    EMBOSSED = 123,
                    ENGRAVED = 122,
                    NONE = 121;
        }

        interface Align
        {
            byte
                    LEFT = 120,
                    CENTER = 119,
                    RIGHT = 118;
        }


        byte
                BR = 117,
                PAPER_COLOR = 116,
                BACK_COLOR = 115,
                FONT_COLOR = 114,
                FONT_INDEX = 113,
                INDENT = 112,
                ITEM = 111;
    }
}



иногда получается достаточно длинно, но читабильно и главное понятно откуда константа и что делает.
С Уважением Сергей Чикирев
Re: Использование enum'ов
От: aefimov Россия
Дата: 15.11.05 09:52
Оценка: 1 (1)
Здравствуйте, Airat Burganov, Вы писали:

AB>Мое мнение, что в таких случаях было бы неплохо вводить в основной класс дополнительные константы вроде

AB>К сожалению объявить State как private и совсем скрыть то, что состояние это enum не получится, так как в таком случае мы лишимся возможности сохранять состояние в переменных.

Мне кажется, что практика использования иннеров "во вне" — это неправильная практика.
public class MyClass {
   public static enum MyEnum {
      MY_VALUE; 
   }
   private final MyEnum value;
   public MyClass(MyEnum value) {
      this.value = value;
   }
   public MyEnum getValue() {
      return value;
   }
}

Т.е. есть класс, который мы хотим инициализировать только ограниченным множеством значений. Мы можем также получить это значение и сравнить его с возможными, чтобы определить тип объекта. Другими словами — у нас логика, присущая только этому объекту вынесена "во вне" самого объекта. Именно это и не правильно на мой взгляд и помойму гораздо понятней будет такой класс:
public class MyClass {
   private static enum MyEnum {
      CAT, DOG; 
   }

   public static MyClass createCat() {
      return new MyClass(MyEnum.CAT);
   }
   
   public static MyClass createDog() {
      return new MyClass(MyEnum.DOG);
   }

   private final MyEnum value;
   private MyClass(MyEnum value) {
      this.value = value;
   }
  
   public boolean isCat() {
      return MyEnum.CAT.equals(value);
   }

   public boolean isDog() {
      return MyEnum.DOG.equals(value);
   }
}

Может я и не прав
Re[2]: Использование enum'ов
От: Airat Burganov Россия http://www.burganov.com
Дата: 15.11.05 10:04
Оценка:
Здравствуйте, aefimov, Вы писали:

A>Здравствуйте, Airat Burganov, Вы писали:

A>Т.е. есть класс, который мы хотим инициализировать только ограниченным множеством значений. Мы можем также получить это значение и сравнить его с возможными, чтобы определить тип объекта. Другими словами — у нас логика, присущая только этому объекту вынесена "во вне" самого объекта. Именно это и не правильно на мой взгляд и помойму гораздо понятней будет такой класс:
A>
A> //skipped
A>

A>Может я и не прав :)

Ну в вашем случае достаточно просто использовать enum, без класса :)
Я имею ввиду использования enum'ов, когда они представляют лишь малуч часть состояния класса, как в Thread'е
Re[5]: Использование enum'ов
От: Lucker Беларусь http://lucker.intervelopers.com/
Дата: 15.11.05 10:13
Оценка: 1 (1)
Здравствуйте, Blazkowicz, Вы писали:

B>Здравствуйте, Airat Burganov, Вы писали:


B>Идея интересная, но все равно не согласен. Читаемость кода страдает. При взгляде на


B>
B>someObject = new SomeClass(SomeClass.XXX);
B>


на мой взгляд читабельность теряется только если в SomeClass используется несколько Enum-ов, если же один, то, ИМХО, вполне даже приемлемый вариант. Я лично использую этот подход. Честно говоря у этого подхода есть еще один дополнительный эффект: ни для кого не секрет, что на более ранних версиях enum эмулируется классами и часто эти классы несколько более интелектуальны, нежели enum. Так вот, бывает необходимость что бы статическая инициализация класса, реализующего enum, выполнялась при статической инициализации внешнего класса. Ну и добиться этого можно сославшись из блока статической инициализации оутера к иннер классу, что и просиходит в случае этого подхода.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[3]: Использование enum'ов
От: aefimov Россия
Дата: 15.11.05 10:16
Оценка:
Здравствуйте, Airat Burganov, Вы писали:

AB>Ну в вашем случае достаточно просто использовать enum, без класса

AB>Я имею ввиду использования enum'ов, когда они представляют лишь малуч часть состояния класса, как в Thread'е

Ну не знаю. Любой состояние можно инкапсулировать в класс.
Re[5]: Использование enum'ов
От: Airat Burganov Россия http://www.burganov.com
Дата: 15.11.05 10:21
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

B>Здравствуйте, Airat Burganov, Вы писали:

B>Идея интересная, но все равно не согласен. Читаемость кода страдает. При взгляде на

B>
B>someObject = new SomeClass(SomeClass.XXX);
B>


B>Не ястно что такое XXX, если константа не называется MODE_XXX, а это выглядит глупо. То есть для того тчобы разобратся надо идти в сырцы или доку классу и смотреть к чему относитя константа. В написании

B>
B>someObject = new SomeClass(SomeClass.Mode.XXX);
B>

B>Сразу понятно к чему относится константа без каких либо дополнительных расследований.

В общем, наверное в каждом конкретном случае по разному. Дело в том, что иногда (и это как раз мой случай) такие названия, как Type или Mode не нужны, потому что все понятно из контекста.
И использования синтаксиса SomeClass.Mode.XXX, только затрудняет понимание. В других случаях, как у vladserge'а, лучше использовать иерархию.
Re[6]: Использование enum'ов
От: dshe  
Дата: 15.11.05 10:22
Оценка:
Здравствуйте, Lucker, Вы писали:

L>на мой взгляд читабельность теряется только если в SomeClass используется несколько Enum-ов, если же один, то, ИМХО, вполне даже приемлемый вариант. Я лично использую этот подход. Честно говоря у этого подхода есть еще один дополнительный эффект: ни для кого не секрет, что на более ранних версиях enum эмулируется классами и часто эти классы несколько более интелектуальны, нежели enum. Так вот, бывает необходимость что бы статическая инициализация класса, реализующего enum, выполнялась при статической инициализации внешнего класса. Ну и добиться этого можно сославшись из блока статической инициализации оутера к иннер классу, что и просиходит в случае этого подхода.


Очень интересно. А пример из жизни можно?
--
Дмитро
Re[4]: Использование enum'ов
От: Airat Burganov Россия http://www.burganov.com
Дата: 15.11.05 10:29
Оценка:
Здравствуйте, aefimov, Вы писали:

A>Здравствуйте, Airat Burganov, Вы писали:


AB>>Ну в вашем случае достаточно просто использовать enum, без класса :)

AB>>Я имею ввиду использования enum'ов, когда они представляют лишь малуч часть состояния класса, как в Thread'е

A>Ну не знаю. Любой состояние можно инкапсулировать в класс.


Да, я не сообразил, Т.е. используются статические методы вместо конструктора и enum превращается лишь в деталь реализации. Иногда это может быть действительно полезно.
Re[7]: Использование enum'ов
От: Lucker Беларусь http://lucker.intervelopers.com/
Дата: 15.11.05 10:36
Оценка:
Здравствуйте, dshe, Вы писали:

D>Очень интересно. А пример из жизни можно?

хе... помню что было, и было нужно, а вот контекста уже не припомню. Извени.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[6]: Использование enum'ов
От: Blazkowicz Россия  
Дата: 15.11.05 10:41
Оценка:
Здравствуйте, Lucker, Вы писали:

L>на мой взгляд читабельность теряется только если в SomeClass используется несколько Enum-ов, если же один, то, ИМХО, вполне даже приемлемый вариант.


Не всегда. Зависит от ситуации. Если из имени константы ясно про что она, то конечно. А если не ясно. То имя энума как раз очень помогает понять.
Re[8]: Использование enum'ов
От: dshe  
Дата: 15.11.05 10:47
Оценка:
Здравствуйте, Lucker, Вы писали:

L>Здравствуйте, dshe, Вы писали:


D>>Очень интересно. А пример из жизни можно?

L>хе... помню что было, и было нужно, а вот контекста уже не припомню. Извени.

Ничего страшного.
--
Дмитро
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.