Как избежать операторов switch-case в Java

java design-patterns enums switch-statement solid-principles

4169 просмотра

1 ответ

У меня есть перечисление TriggerType, где могут быть добавлены различные триггеры

public enum TriggerType {
    meta,data,list,toggle
}

Эти типы триггеров используются внутри разных обработчиков (например, Component, Dashboard и т. Д.), Чтобы определить, какой триггер запускается внутри обработчика через случай переключения, например, фрагмент кода Code для ComponentHandler, использующий запуск через случай переключения, приведен ниже.

@Override
public TriggerResultInterface executeTriggerJob(TriggerEventHelper triggerEventHelper) throws TriggerHandlerException {
    switch (triggerEventHelper.getTriggerName()) {
        case meta:
            return getMetaComponentConfig(triggerEventHelper);
        case data:
            return getComponentData(triggerEventHelper);
        default:
            LOGGER.debug(INVALID_TRIGGER_NAME_CONFIGURED);
            throw new TriggerHandlerException(INVALID_TRIGGER_NAME_CONFIGURED);
    }

}

Представьте себе, если я хочу добавить новый Trigger, я должен обновить класс enum, что неизбежно, в то же время я должен обновить каждый из моих классов-обработчиков, которые необходимо использовать для этого Trigger. Является ли этот способ проектирования с кодированием хорошо или есть какое-либо другое лучшее решение, которое улучшит этот код и будет следовать принципам SOLID вместе с лучшим дизайном.

Я хотел бы подчеркнуть, что этот вопрос не является дубликатом этого . В этой ситуации требуется только одно поведение для каждого типа (например: convertToMp3). Но мой вопрос относится к тому, что мой тип перечисления (тип триггера) зависит от обработчиков, которые он мог бы использовать, поэтому поведение или реализация каждого перечисления типа триггера будет зависеть от требований используемого обработчика.

Автор: Keshan Nageswaran Источник Размещён: 08.11.2019 10:58

Ответы (1)


3 плюса

Решение

Одним из решений является использование полиморфизма для другой обработки триггеров. Например, вы можете объявить Triggerинтерфейс и иметь несколько реализаций. В этом случае, когда вам нужен новый тип триггера, вы просто реализуете этот интерфейс и не трогаете существующий код:

public interface Trigger {
    TriggerResultInterface execute(TriggerEventHelper eventHelper);
}

public class MetaTrigger implements Trigger {
    @Override
    TriggerResultInterface execute(TriggerEventHelper eventHelper) {
        // do meta trigger work here
    }
}

public class DataTrigger implements Trigger {
    @Override
    TriggerResultInterface execute(TriggerEventHelper eventHelper) {
        // do data trigger work here
    }
}

// ...

public TriggerResultInterface executeTriggerJob(TriggerEventHelper eventHelper) {
    eventHelper.getTrigger().execute(eventHelper);
}

В этом случае будет невозможно добавить новый тип триггера и не реализовывать его поведение.

Если вам нужна реализация по умолчанию, вы можете использовать базовый класс вместо интерфейса (в Java 8 вы можете добавить реализацию по умолчанию прямо в интерфейс).

Автор: Andrew Lygin Размещён: 20.08.2016 07:11
Вопросы из категории :
32x32