Я предпочитаю делегацию или состав или класс фабрики (в зависимости от проблемы, которая приводит к этой проблеме) постараться не делать его общедоступным классом.
, Если бы это - "интерфейс/классы реализации в различных пакетах" проблема, тогда я использовал бы общедоступный класс фабрики, который будет в том же пакете как impl пакет и предотвращать воздействие impl класса.
, Если это, "Я очень не хочу обнародовать этот класс/метод только для обеспечения этой функциональности для некоторого другого класса в различном пакете" проблема, тогда я использовал бы общедоступный класс делегата в том же пакете и представил бы только что часть функциональности, необходимой классу "постороннего".
Некоторые из этих решений управляются целевым сервером classloading архитектура (пакет OSGi, ВОЙНА/EAR, и т.д.), развертывание и соглашения о присвоении имен пакета. Например, вышеупомянутое предлагаемое решение, 'Друг Средство доступа' шаблон умен для нормальных JAVA-приложений. Интересно, становится ли это хитрым для реализации его в OSGi из-за различия в стиле classloading.
По второстепенному вопросу, может быть лучше использовать 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
}
Использование порядкового номера перечисления для вашего использования зависит от неявного порядка. Мне нравится быть явным, особенно если вы используете целочисленные значения в качестве индекса в вашем массиве, связывая значение со смыслом.
В этом случае я бы предпочел использовать final static int NORTH = 0
и т. Д.
Если вы не сохраняете массивы или каким-либо иным образом становитесь зависимыми от разных версии вашего класса перечисления, безопасно использовать 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;
}
}
Отсюда легко обеспечить легкий поиск индекса для направления (путем создания карты в статическом блоке для компактного сохранения; выполнить проверку уникальности в статическом блоке и т. Д.
Вы также можете улучшить перечисление (индекс по часовой стрелке):
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;
}
}
Я настоятельно не рекомендую это делать, потому что порядковое значение основано на порядке в вашем 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)
В документации только сказано, что большинству программистов этот метод не нужен. Это один из случаев законного использования. Предполагая, что ваш класс управляет как перечислением, так и массивом , нет причин опасаться метода ordinal ()
для индексации массива (поскольку вы всегда можете синхронизировать их).
Однако, если ваше использование станет более сложным, вы, вероятно, захотите использовать вместо него EnumMap
, как было предложено.
В JavaDoc говорится
] Большинство программистов не будут использовать Этот метод. Он предназначен для использования сложные данные на основе перечисления структуры, такие как EnumSet и EnumMap.
Я думаю, они хотят сказать, что большинство программистов предпочтут использовать EnumMap или EnumSet, а не вручную индексировать массив. Они, конечно, не означают, что вы должны заменить перечисление парой целочисленных переменных, поскольку при этом вы потеряете безопасность типов.
Если вам нужна гибкость, чтобы иметь возможность переупорядочивать константы перечисления без изменения порядка в массив, вы можете изолировать индекс в другом поле перечисления, как было описано Арне.