当前位置:   article > 正文

巧妙替代 if - else 的方案之枚举_枚举代替if else

枚举代替if else

场景:当我们的项目中需要接收到一些数据并且需要对其进行处理时,由于它们来自于不同的渠道(如:阿里、腾讯),不同渠道所需要的处理方式不同,下面我们写一个常见的 Demo 来实现该场景。

1、首先,构建一个基础规则的抽象类 GeneralChannelRule,定义一个抽象方法 process(),不同的渠道都需要实现该抽象方法。

  1. public abstract class GeneralChannelRule {
  2. public abstract void process();
  3. }

2、建立一个简单的枚举类。

  1. public enum ChannelRuleEnum {
  2. ALIBABA("Alibaba"),
  3. TENCENT("Tencent");
  4. private String code;
  5. ChannelRuleEnum(String channel) {
  6. this.code = channel;
  7. }
  8. public String getCode() {
  9. return code;
  10. }
  11. public void setCode(String code) {
  12. this.code = code;
  13. }
  14. }

3、定义一个阿里的规则类,用来处理对于阿里渠道数据的具体处理逻辑。

  1. public class AlibabaChannelRule extends GeneralChannelRule {
  2. @Override
  3. public void process() {
  4. // Alibaba 数据处理逻辑
  5. System.out.println("This is Alibaba");
  6. }
  7. }

4、定义一个腾讯的规则类,用来处理对于腾讯渠道数据的具体处理逻辑。

  1. public class TencentChannelRule extends GeneralChannelRule {
  2. @Override
  3. public void process() {
  4. // Tencent 数据处理逻辑
  5. System.out.println("This is Tencent");
  6. }
  7. }

5、使用规则对数据进行处理。

  1. public class Demo {
  2. public static void main(String[] args) {
  3. // 模拟接收到的数据是来自 Alibaba
  4. String channel = "Alibaba";
  5. GeneralChannelRule rule = null;
  6. if (ChannelRuleEnum.ALIBABA.getCode().equals(channel)) {
  7. rule = new AlibabaChannelRule();
  8. } else if (ChannelRuleEnum.TENCENT.getCode().equals(channel)) {
  9. rule = new TencentChannelRule();
  10. } else {
  11. // 无匹配项
  12. }
  13. // 执行逻辑
  14. rule.process();
  15. }
  16. }

6、如图为实现结果。

通过如上的方式,能够实现需求。

但是存在两个缺点:

其一、当我们需要新增新的渠道的时候,需要对 main 方法中的逻辑进行修改调整。这一点违背了设计模式中的开放封闭规则。开放封闭规则的核心思想是软件实体是可扩展而不可修改的。也就是说,对扩展是开放的,而对修改则是封闭的。

其二、新增渠道后,修改代码会产生大量的 if - else,不太优雅。

为了解决以上的两个问题,我们可以借助枚举类来进行优化。

1、调整一下枚举类,增加一个属性 GeneralChannelRule,且给对应的渠道构建对应的实现类 GeneralChannelRule,同时新增一个匹配方法 match()。 

  1. public enum ChannelRuleEnum {
  2. ALIBABA("Alibaba", new AlibabaChannelRule()),
  3. TENCENT("Tencent", new TencentChannelRule());
  4. private String code;
  5. private GeneralChannelRule channelRule;
  6. /**
  7. * 匹配
  8. * @param code 渠道值
  9. * @return
  10. */
  11. public static ChannelRuleEnum match(String code){
  12. ChannelRuleEnum[] values = ChannelRuleEnum.values();
  13. for (ChannelRuleEnum value : values) {
  14. if(value.code.equals(code)){
  15. return value;
  16. }
  17. }
  18. return null;
  19. }
  20. ChannelRuleEnum(String channel, GeneralChannelRule channelRule) {
  21. this.code = channel;
  22. this.channelRule = channelRule;
  23. }
  24. public GeneralChannelRule getChannelRule() {
  25. return channelRule;
  26. }
  27. public void setChannel(GeneralChannelRule channelRule) {
  28. this.channelRule = channelRule;
  29. }
  30. public String getCode() {
  31. return code;
  32. }
  33. public void setCode(String code) {
  34. this.code = code;
  35. }
  36. }

2、改写程序。

  1. public class Demo {
  2. public static void main(String[] args) {
  3. // 模拟接收到的数据是来自 Tencent
  4. String channel = "Tencent";
  5. ChannelRuleEnum channelRule = ChannelRuleEnum.match(channel);
  6. GeneralChannelRule rule = channelRule.getChannelRule();
  7. rule.process();
  8. }
  9. }

3、如下为实现结果。

通过使用枚举类,在枚举中将 key 与渠道规则具体实现进行绑定。通过优化,可以减少 if - else 使得代码更加优雅。同时,如果需要新增渠道,还需要做两步操作即可完成。这样就不需要改动原有的代码逻辑,符合了开放封闭原则。 操作步骤如下:

  1. 定义新增渠道实现类,继承 GeneralChannelRule 抽象类,且实现其抽象方法 process()。
  2. 在枚举类 ChannelRuleEnum 新增对应的渠道实现类。

以上就是通过枚举类的方式来巧妙替代 if - else 的方案,对于替代 if - else 的优秀解决方案还有很多(如:策略模式、工厂模式等),感兴趣的朋友可以查阅相关的资料。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/377850
推荐阅读
相关标签
  

闽ICP备14008679号