Как удалить зависимость от значений перечисления Java?

[ Обратите внимание на пробел: Я знаю, что лучшим решением было бы полностью избавиться от перечисления, но это не вариант на сегодняшний день, как упоминалось в комментариях, но он запланирован на ( далекое) будущее.]

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

Строковые константы

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

Класс-оболочка

Другое решение - использование класса-оболочки с тем же интерфейсом, что и перечисление. Перечисление становится классом-оболочкой, а значения перечисления становятся константами внутри этой оболочки. Мне пришлось написать код десериализации, чтобы гарантировать идентичность объекта (как это делают перечисления), но я не знаю, правильное ли это решение. Что делать, если используются разные загрузчики классов? но это вызвало бы множество небольших изменений во внешнем интерфейсе. Я ищу решение, которое вызывает как можно меньше изменений во внешнем интерфейсе.

Класс-оболочка

Другое решение - использование класса-оболочки с тем же интерфейсом, что и перечисление. Перечисление становится классом-оболочкой, а значения перечисления становятся константами внутри этой оболочки. Мне пришлось написать код десериализации, чтобы гарантировать идентичность объекта (как это делают перечисления), но я не знаю, правильное ли это решение. Что делать, если используются разные загрузчики классов? но это вызвало бы множество небольших изменений во внешнем интерфейсе. Я ищу решение, которое вызывает как можно меньше изменений во внешнем интерфейсе.

Класс-оболочка

Другое решение - использование класса-оболочки с тем же интерфейсом, что и перечисление. Перечисление становится классом-оболочкой, а значения перечисления становятся константами внутри этой оболочки. Мне пришлось написать код десериализации, чтобы гарантировать идентичность объекта (как это делают перечисления), но я не знаю, правильное ли это решение. Что делать, если используются разные загрузчики классов? Мне пришлось написать код десериализации, чтобы гарантировать идентичность объекта (как это делают перечисления), но я не знаю, правильное ли это решение. Что делать, если используются разные загрузчики классов? Мне пришлось написать код десериализации, чтобы гарантировать идентичность объекта (как это делают перечисления), но я не знаю, правильное ли это решение. Что делать, если используются разные загрузчики классов? Класс-оболочка будет реализовывать интерфейс Java, который заменит перечисление в бэкэнде. Но будет ли код десериализации выполняться в бэкэнде даже в этом случае?

Пример для класса-оболочки:

public class Locomotion implements Serializable {
    private static final long serialVersionUID = -6359307469030924650L;

    public static final List<Locomotion> list = new ArrayList<Locomotion>();

    public static final Locomotion CAR = createValue(4654L);
    public static final Locomotion CYCLE = createValue(34235656L);
    public static final Locomotion FEET = createValue(87687L);

    public static final Locomotion createValue(long type) {
        Locomotion enumValue = new Locomotion(type);
        list.add(enumValue);
        return enumValue;
    }

    private final long ppId;

    private Locomotion(long type) {
        this.ppId = type;
    }

    private Object readResolve() throws ObjectStreamException {
        for (Locomotion enumValue : list) {
            if (this.equals(enumValue)) {
                return enumValue;
            }
        }
        throw new InvalidObjectException("Unknown enum value '" + ppId + "'");
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + (int) (ppId ^ (ppId >>> 32));
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (!(obj instanceof Locomotion)) {
            return false;
        }
        Locomotion other = (Locomotion) obj;
        if (ppId != other.ppId) {
            return false;
        }
        return true;
    }
}

У вас уже была такая же проблема? Как вы ее решили?

5
задан Christian Strempfer 8 April 2011 в 10:02
поделиться