Это - плохая практика для использования порядкового номера Перечисления для индексации массива в Java?

Я предпочитаю делегацию или состав или класс фабрики (в зависимости от проблемы, которая приводит к этой проблеме) постараться не делать его общедоступным классом.

, Если бы это - "интерфейс/классы реализации в различных пакетах" проблема, тогда я использовал бы общедоступный класс фабрики, который будет в том же пакете как impl пакет и предотвращать воздействие impl класса.

, Если это, "Я очень не хочу обнародовать этот класс/метод только для обеспечения этой функциональности для некоторого другого класса в различном пакете" проблема, тогда я использовал бы общедоступный класс делегата в том же пакете и представил бы только что часть функциональности, необходимой классу "постороннего".

Некоторые из этих решений управляются целевым сервером classloading архитектура (пакет OSGi, ВОЙНА/EAR, и т.д.), развертывание и соглашения о присвоении имен пакета. Например, вышеупомянутое предлагаемое решение, 'Друг Средство доступа' шаблон умен для нормальных JAVA-приложений. Интересно, становится ли это хитрым для реализации его в OSGi из-за различия в стиле classloading.

19
задан Scorcher84 15 October 2009 в 19:37
поделиться

7 ответов

По второстепенному вопросу, может быть лучше использовать EnumMap для ваших соседей:

Map<Dir, Cell> neighbours = 
    Collections.synchronizedMap(new EnumMap<Dir, Cell>(Dir.class));

neighbours.put(Dir.North, new Cell());

for (Map.Entry<Dir, Cell> neighbour : neighbours.entrySet()) {
    if (neighbour.isVisited()) { ... }
}

etc..

BTW: экземпляры Enum по соглашению должны быть полностью заглавными,

enum Dir {
    NORTH,
    EAST, 
    SOUTH,
    WEST
}
16
ответ дан 30 November 2019 в 02:41
поделиться

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

В этом случае я бы предпочел использовать final static int NORTH = 0 и т. Д.

1
ответ дан 30 November 2019 в 02:41
поделиться

Если вы не сохраняете массивы или каким-либо иным образом становитесь зависимыми от разных версии вашего класса перечисления, безопасно использовать ordinal () .

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

public enum Direction {
  NORTH(0),
  SOUTH(1),
  EAST(2),
  WEST(3);

  private int _index;

  private Direction (int index_)
  {
    _index = index_;
  }

  public int getIndex()
  {
    return _index;
  }
}

Отсюда легко обеспечить легкий поиск индекса для направления (путем создания карты в статическом блоке для компактного сохранения; выполнить проверку уникальности в статическом блоке и т. Д.

2
ответ дан 30 November 2019 в 02:41
поделиться

Вы также можете улучшить перечисление (индекс по часовой стрелке):

enum Dir
{
  NORTH(0),
  SOUTH(2),
  EAST(1),
  WEST(3);

  private final int index;

  private Dir(int index) {
    this.index = index;
  }

  public int getIndex() {
    return index;
  }

}
13
ответ дан 30 November 2019 в 02:41
поделиться

Я настоятельно не рекомендую это делать, потому что порядковое значение основано на порядке в вашем Java-коде.

Использование ordinal () затруднит поддержку кода, особенно если некоторые форма настойчивости входит в уравнение.

например, если вы решили добавить диагональные направления, такие как NORTH_WEST, SOUTH_EAST. если вы используете ordinal (), вы должны добавить их в конец списка, иначе то, что раньше было ЮГОМ, может стать СЕВЕРМ.

т.е. вы можете изменить свой enyum на без (возможно) изменения функциональности

N  (is now 0 was 0) 
NE (is now 1) 
E (is now 2 was 1) 
SE (is now 3 ) 
S  (is mow 4 was 2) 
SW (is now 5) 
W  (is now 6 was 3)
1
ответ дан 30 November 2019 в 02:41
поделиться

В документации только сказано, что большинству программистов этот метод не нужен. Это один из случаев законного использования. Предполагая, что ваш класс управляет как перечислением, так и массивом , нет причин опасаться метода ordinal () для индексации массива (поскольку вы всегда можете синхронизировать их).

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

13
ответ дан 30 November 2019 в 02:41
поделиться

В JavaDoc говорится

] Большинство программистов не будут использовать Этот метод. Он предназначен для использования сложные данные на основе перечисления структуры, такие как EnumSet и EnumMap.

Я думаю, они хотят сказать, что большинство программистов предпочтут использовать EnumMap или EnumSet, а не вручную индексировать массив. Они, конечно, не означают, что вы должны заменить перечисление парой целочисленных переменных, поскольку при этом вы потеряете безопасность типов.

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

3
ответ дан 30 November 2019 в 02:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: