【问题标题】:How to avoid switch-case statements in Java [duplicate]如何避免 Java 中的 switch-case 语句
【发布时间】:2016-08-20 06:49:44
【问题描述】:

我有一个 TriggerType 的枚举,可以添加不同的触发器

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

这些触发器类型在不同的处理程序(例如组件、仪表板等)中使用,以识别在处理程序内部通过 switch-case 触发哪个触发器,例如,通过 switch-case 使用触发器的 ComponentHandler 的代码 sn-p 如下所示

@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 原则以及更好的设计。

我想强调的是,这个问题不是 this 的重复。在这种情况下,每种类型只需要一种行为(例如:convertToMp3)。但是我的问题指的是我的枚举类型(触发器类型)取决于它可能使用的处理程序,因此每个触发器类型枚举的行为或实现将取决于它正在使用的处理程序的要求。

【问题讨论】:

  • 将方法放入 Enum 中,并覆盖每个值。我发现在实践中这样做的价值有限,因为您必须为每种方法提供各种外部上下文,这会破坏 Enum 的独立能力,但如果您可以限制这种破坏,它可能是一种有用的技术。
  • answer I wrote 为您介绍今天早些时候的上下文处理程序,您就是这样做的
  • @kesh 如果你仔细观察,这个想法实际上是一样的。您想根据选择的值执行行为(在另一个问题中,它正在创建一个对象。在这个问题中,它正在调用带有参数的函数)。与其检查值并根据值调用函数,不如简单地给值函数,然后从值调用它。切换使用哪个值会切换执行哪个行为。这就是polymorphism的定义。
  • 正如文斯已经解释的那样,请不要对代码库中的每个 switch-case 提出新问题
  • 您可以查看的另一件事是访问者模式。

标签: java design-patterns enums switch-statement solid-principles


【解决方案1】:

其中一种解决方案是使用多态性以不同方式处理触发器。例如,您可以声明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 中,您可以直接在接口中添加默认实现)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多