В моем приложении Java 8 есть запах кода, который я хотел бы устранить путем некоторого изменения дизайна.
Я объявил Enum DataType
, который содержит не только значения enum, но и упорядоченный список этих значений enum, основанный на некоторой логике.Подводя итог, каждое значение перечисления объявляет набор зависимостей от других значений перечисления (того же типа), и список представляет собой топологически отсортированный список этих значений перечисления.Каждое значение перечисления также имеет Calculator
, связанное с ним.
public Enum DataType
{
A(EnumSet.noneOf(DataType.class), new CalculatorA()),
B(EnumSet.of(A), new CalculatorB()),
C(EnumSet.noneOf(DataType.class), new CalculatorC()),
D(EnumSet.Of(A,B,C), new CalculatorD()),
... more ...
...constructor and attributes...
public static final List<DataType> DATA_TYPES_SORTED_BY_DEPENDENCIES;
static
{
DATA_TYPES_SORTED_BY_DEPENDENCIES = ...
}
}
Я знаю, что перечисления естественным образом упорядочены (порядковые), и, таким образом, при объявлении их в правильном порядке, нет необходимости выполнять какую-либо сортировку,Однако количество значений enum велико и может со временем меняться.Я не хочу обременять себя поддержанием правильного порядка, я хочу, чтобы программа делала это для меня, если я просто объявляю зависимости.Это также самообъясняющий код, потому что прямо сказано, что существуют определенные зависимости и что они отсортированы.
Цель моей программы - запускать калькуляторы на множестве записей в правильном порядке, поэтому, почемуперечисление упорядочено:
for(Record r : records)
{
for(DataType type : DataType.DATA_TYPES_SORTED_BY_DEPENDENCIES)
{
Integer result = type.getCalculator().calculate(r);
r.getDataMap().put(type, result);
}
}
Эта установка работала нормально, пока не пришло требование, чтобы калькуляторы, которые раньше статически создавались в классе перечисления, должны быть параметризуемыми.Параметры будут поступать из веб-службы или из базы данных.Я должен установить классы Calculator
вне перечисления, и теперь я потерял связь между типами перечислений и калькуляторами.
Чтобы исправить это, я создал HashMap для простого поиска:
...get some parameters from another service...
Map<DataType, Calculator> calculatorsByTypeMap = new HashMap<>(400);
calculatorsByTypeMap.put(DataType.A, new CalculatorA(someParameterA));
calculatorsByTypeMap.put(DataType.B, new CalculatorB());
calculatorsByTypeMap.put(DataType.C, new CalculatorC(someParameterC1, somereParameterC2));
calculatorsByTypeMap.put(DataType.D, new CalculatorD(someParameterD));
...
return calculatorsByTypeMap;
Это беспокоит меня, потому что я концептуально объявил мое (довольно большое) перечисление дважды: один раз для логики упорядочения и один раз для связи с калькуляторами.Есть ли способ предотвратить это?