精选枚举代替开关

问题及其解决方案

开关/案例是用大多数命令式编程语言实现的通用控制结构。 开关比一系列的if / else更具可读性。

这是一个简单的示例:

// Switch with int literal
switch (c) {
  case 1: one(); break;
  case 2: two(); break;
  case 3: three(); break;
  default: throw new UnsupportedOperationException(String.format("Operation %d is not supported", c));
}

这是此代码中的主要问题的列表:

  1. int文字(1、2、3)与执行的代码之间的关系并不明显。
  2. 如果不再支持其中一个值(例如2),并且此开关未相应更新,它将永远包含未使用的代码。
  3. 如果引入了c的新可能值(例如4),并且未相应更新开关,则代码可能会在运行时抛出UnsupportedOperationException而没有任何编译时通知。
  4. 这种开关结构倾向于在代码中重复几次,从而使问题2和3更加复杂。

最简单的解决方法是使用int常量而不是文字。 首先,让我们定义常量:

private static int ONE = 1;
private static int TWO = 2;
private static int THREE = 3;

现在,代码将如下所示:

switch (c) {
  case ONE: one(); break;
  case TWO: two(); break;
  case THREE: three(); break;
  default: throw new UnsupportedOperationException(String.format("Operation %d is not supported", c));
}

(显然,在现实生活中,常量的名称必须是自描述的)
此代码段更具可读性,但所有其他缺点仍然相关。 改进初始代码段的下一个尝试使用2004年在版本5中引入Java语言的enums 。让我们定义以下enum

enum Action {ONE, TWO, THREE}

现在,开关片段将稍作更改:

Action a = ...
switch (a) {
  case ONE: one(); break;
  case TWO: two(); break;
  case THREE: three(); break;
  default: throw new UnsupportedOperationException(String.format("Operation %s is not supported", a));
}

这段代码要好一点:如果从enum Action删除其中一个元素,它将产生编译错误。 但是,如果将其他元素添加到enum Action ,则不会导致编译错误。 在这种情况下,某些IDE或静态代码分析工具可能会产生警告,但是谁在注意警告呢? 幸运的是, enum可以声明必须由每个元素实现的抽象方法:

enum Action {
  ONE { @Override public void action() { } }, 
  TWO { @Override public void action() { } }, 
  THREE { @Override public void action() { } }, 
  public abstract void action();
}

现在,switch语句可以用单行替换:

Action a = ...
a.action();

此解决方案没有上面列举的任何缺点:

  1. 这是可读的。 该方法“附加”到enum元素。 如果方法含义不清楚,则可以编写所需数量的javadoc 。 调用方法的代码很简单:什么比方法调用更简单?
  2. 在不删除实现的情况下无法删除enum常量,因此,如果某些功能不再相关,则不会保留任何未使用的代码。
  3. 如果没有实现action()方法,则无法添加新的enum元素。 没有实现的代码无法编译。
  4. 如果需要执行多个操作,则可以在枚举中全部执行。 正如我们已经提到的,调用特定功能的代码是微不足道的,因此现在没有代码重复了。

结论

尽管开关/外壳结构是众所周知的,并且以各种编程语言广泛使用,但是其使用可能会引起很多问题。 上面描述的使用Java枚举的解决方案没有这些缺点。 本系列的下一篇文章展示了如何扩展现有enum功能。

翻译自: https://www.javacodegeeks.com/2019/03/featured-enum-instead-switch.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值