合规国际互联网加速 OSASE为企业客户提供高速稳定SD-WAN国际加速解决方案。 广告
### 使用常量相关的方法 常量相关的方法允许我们为每个 enum 实例提供方法的不同实现,这使得常量相关的方法似乎是实现多路分发的完美解决方案。不过,通过这种方式,enum 实例虽然可以具有不同的行为,但它们仍然不是类型,不能将其作为方法签名中的参数类型来使用。最好的办法是将 enum 用在 switch 语句中,见下例: ```java // enums/RoShamBo3.java // Using constant-specific methods // {java enums.RoShamBo3} package enums; import static enums.Outcome.*; public enum RoShamBo3 implements Competitor<RoShamBo3> { PAPER { @Override public Outcome compete(RoShamBo3 it) { switch(it) { default: // To placate the compiler case PAPER: return DRAW; case SCISSORS: return LOSE; case ROCK: return WIN; } } }, SCISSORS { @Override public Outcome compete(RoShamBo3 it) { switch(it) { default: case PAPER: return WIN; case SCISSORS: return DRAW; case ROCK: return LOSE; } } }, ROCK { @Override public Outcome compete(RoShamBo3 it) { switch(it) { default: case PAPER: return LOSE; case SCISSORS: return WIN; case ROCK: return DRAW; } } }; @Override public abstract Outcome compete(RoShamBo3 it); public static void main(String[] args) { RoShamBo.play(RoShamBo3.class, 20); } } ``` 输出为: ``` ROCK vs. ROCK: DRAW SCISSORS vs. ROCK: LOSE SCISSORS vs. ROCK: LOSE SCISSORS vs. ROCK: LOSE PAPER vs. SCISSORS: LOSE PAPER vs. PAPER: DRAW PAPER vs. SCISSORS: LOSE ROCK vs. SCISSORS: WIN SCISSORS vs. SCISSORS: DRAW ROCK vs. SCISSORS: WIN SCISSORS vs. PAPER: WIN SCISSORS vs. PAPER: WIN ROCK vs. PAPER: LOSE ROCK vs. SCISSORS: WIN SCISSORS vs. ROCK: LOSE PAPER vs. SCISSORS: LOSE SCISSORS vs. PAPER: WIN SCISSORS vs. PAPER: WIN SCISSORS vs. PAPER: WIN SCISSORS vs. PAPER: WIN ``` 虽然这种方式可以工作,但是却不甚合理,如果采用 RoShamB02.java 的解决方案,那么在添加一个新的类型时,只需更少的代码,而且也更直接。 :然而,RoShamBo3.java 还可以压缩简化一下: ```java // enums/RoShamBo4.java // {java enums.RoShamBo4} package enums; public enum RoShamBo4 implements Competitor<RoShamBo4> { ROCK { @Override public Outcome compete(RoShamBo4 opponent) { return compete(SCISSORS, opponent); } }, SCISSORS { @Override public Outcome compete(RoShamBo4 opponent) { return compete(PAPER, opponent); } }, PAPER { @Override public Outcome compete(RoShamBo4 opponent) { return compete(ROCK, opponent); } }; Outcome compete(RoShamBo4 loser, RoShamBo4 opponent) { return ((opponent == this) ? Outcome.DRAW : ((opponent == loser) ? Outcome.WIN : Outcome.LOSE)); } public static void main(String[] args) { RoShamBo.play(RoShamBo4.class, 20); } } ``` 输出为: ``` PAPER vs. PAPER: DRAW SCISSORS vs. PAPER: WIN SCISSORS vs. PAPER: WIN SCISSORS vs. PAPER: WIN ROCK vs. SCISSORS: WIN ROCK vs. ROCK: DRAW ROCK vs. SCISSORS: WIN PAPER vs. SCISSORS: LOSE SCISSORS vs. SCISSORS: DRAW PAPER vs. SCISSORS: LOSE SCISSORS vs. ROCK: LOSE SCISSORS vs. ROCK: LOSE PAPER vs. ROCK: WIN PAPER vs. SCISSORS: LOSE SCISSORS vs. PAPER: WIN ROCK vs. SCISSORS: WIN SCISSORS vs. ROCK: LOSE SCISSORS vs. ROCK: LOSE SCISSORS vs. ROCK: LOSE SCISSORS vs. ROCK: LOSE ``` 其中,具有两个参数的 compete() 方法执行第二个分发,该方法执行一系列的比较,其行为类似 switch 语句。这个版本的程序更简短,不过却比较难理解,对于一个大型系统而言,难以理解的代码将导致整个系统不够健壮。