Случилось однажды так, что моего хорошего коллегу, программирующего на Flex, перевели на проект, где использовался Ext GWT. Периодически приходилось отвечать на вопросы: «Как сделать то-то и то-то в Java?» и «Почему этого нет и как это обойти?». ActionScript, на котором мой коллега привык писать, в сравнении с Java был более гибким и позволял не особо заморачиваться на предмет приведения и описания типов переменных. Каким же было его удивление, когда в конструкции switch невозможно было делать сравнения переменных типа String. Хотя, казалось бы, существует множество технических ситуаций, когда такой switch пригодился бы (обработка разных сценариев в зависимости от содержимого переданной переменной String).
Благо, в настоящее время данная функциональность реализована в Java 7. Однако, в связи с тем, что переход на Java 7 не будет совершен моментально в большинстве проектов, то я хочу с радостью поделиться собственным «эстетическим» способом, чтобы избежать громоздких конструкций if..then..else.
Предположим, что у нас есть переменная type, которая может принимать значения «RequestOne», «RequestTwo», «RequestThree» и в зависимости от этого будут выполняться разные сценарии.
В простейшем случае, код метода, обрабатывающего запрос, мог бы выглядеть так:
Код может быть неудобным для чтения, если type будет принимать длинные строки или для одного сценария может быть несколько вариантов значений type. В данном случае на помощь приходит перечисляемый тип: enum. Описывает перечисляемый тип RequestType следующим образом:
И тогда метод processRequest(String) преобразуется следующим образом:
Конечно, статический метод getType в перечисляемом типе RequestType не оптимальный, особенно, если речь идет о большом количестве возможных значений type. Но при таком подходе получается хранить список строковых значений type в одном месте и конструкция switch смотрится лаконично. Соответственно, добавление новых значений type и редактирование старых может происходить на порядок быстрее, что приводит к повышению производительности труда.
В конечном счете, соглашусь, это не лучшее решение с точки зрения производительности, но достаточно неплохой пример использования перечисляемых типов для случая, описанного выше.
Благо, в настоящее время данная функциональность реализована в Java 7. Однако, в связи с тем, что переход на Java 7 не будет совершен моментально в большинстве проектов, то я хочу с радостью поделиться собственным «эстетическим» способом, чтобы избежать громоздких конструкций if..then..else.
Предположим, что у нас есть переменная type, которая может принимать значения «RequestOne», «RequestTwo», «RequestThree» и в зависимости от этого будут выполняться разные сценарии.
В простейшем случае, код метода, обрабатывающего запрос, мог бы выглядеть так:
public void processRequest(String type) {
if (type.equals("RequestOne")) {
scenarioOne();
} else if (type.equals("RequestTwo")) {
scenarioTwo();
} else if (type.equals("RequestThree")) {
scenarioThree();
}
}
Код может быть неудобным для чтения, если type будет принимать длинные строки или для одного сценария может быть несколько вариантов значений type. В данном случае на помощь приходит перечисляемый тип: enum. Описывает перечисляемый тип RequestType следующим образом:
public enum RequestType {
SCENARIO_ONE("RequestOne"),
SCENARIO_TWO("RequestTwo"),
SCENARIO_THREE("RequestThree");
private String typeValue;
private RequestType(String type) {
typeValue = type;
}
static public RequestType getType(String pType) {
for (RequestType type: RequestType.values()) {
if (type.getTypeValue().equals(pType)) {
return type;
}
}
throw new RuntimeException("unknown type");
}
public String getTypeValue() {
return typeValue;
}
}
И тогда метод processRequest(String) преобразуется следующим образом:
public void processRequest(String type) {
RequestType request = RequestType.getType(type);
switch(request) {
case SCENARIO_ONE: scenarioOne(); break;
case SCENARIO_TWO: scenarioTwo(); break;
case SCENARIO_THREE: scenarioThree(); break;
}
}
Конечно, статический метод getType в перечисляемом типе RequestType не оптимальный, особенно, если речь идет о большом количестве возможных значений type. Но при таком подходе получается хранить список строковых значений type в одном месте и конструкция switch смотрится лаконично. Соответственно, добавление новых значений type и редактирование старых может происходить на порядок быстрее, что приводит к повышению производительности труда.
В конечном счете, соглашусь, это не лучшее решение с точки зрения производительности, но достаточно неплохой пример использования перечисляемых типов для случая, описанного выше.