Связать значения Java Enum с динамически создаваемыми объектами - PullRequest
1 голос
/ 28 июня 2019

В моем приложении 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;

Это беспокоит меня, потому что я концептуально объявил мое (довольно большое) перечисление дважды: один раз для логики упорядочения и один раз для связи с калькуляторами.Есть ли способ предотвратить это?

1 Ответ

0 голосов
/ 27 июля 2019

Постройте перечисление с нулевым полем калькулятора. Во время выполнения выполните топологическую сортировку и создайте отсортированный список. Получить новые калькуляторы и установить значение калькулятора в перечислении.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...