最近接到了一个新需求,按照不同的编码去执行不同的逻辑,但最后返回的数据类型是一致的,都是相同对象的List集合。
完成这个需求的话可以使用if-else来执行不同的方法,虽然if-else可以实现,但if-else是一种面向过程的实现。尽管这个需求中编码是固定的,但编码也太多了,如果用if-else写出来可读性估计也不高。
这个时候就想到之前无意中看到过一篇文章,文章的大致内容,就是使用策略+枚举的方式去解决if-else。正好今天用到了,那么就展开说说怎么使用策略+枚举的方式怎么来替换掉if-else吧.
举个例子吧,比如说每周有7天,我每天都回家做不同的菜,根据入参1-7代表周一到周日,提醒我今天该做什么菜了,那么我们就使用if-else来实现的话,代码是这样的。
public static void main(String[] args) { //获取今天是周几 LocalDate today = LocalDate.now(); DayOfWeek dayOfWeek = today.getDayOfWeek(); int dayOfWeekValue = dayOfWeek.getValue(); if(dayOfWeekValue == 1){ System.out.println("今天是周一,今天做农家一碗香。"); }else if(dayOfWeekValue == 2){ System.out.println("今天是周二,今天做鱼香肉丝。"); }else if(dayOfWeekValue == 3){ System.out.println("今天是周三,今天做韭菜鸡蛋。"); }else if(dayOfWeekValue == 4){ System.out.println("今天是周四,今天做回锅肉。"); }else if(dayOfWeekValue == 5){ System.out.println("今天是周五,今天做蛋炒饭。"); }else if(dayOfWeekValue == 6){ System.out.println("今天是周六,今天做麻婆豆腐。"); }else if(dayOfWeekValue == 7){ System.out.println("今天是周日,今天做土豆丝。"); }else{ throw new ServiceException("今天是周几,今天做什么菜?"); } }
如果我们用枚举+策略去实现呢?
首先我们先定义一个这样的枚举
@Getter public enum DoTheCookingEnum { MONDAY(1), TUESDAY(2), WEDNESDAY(3), THURSDAY(4), FRIDAY(5), SATURDAY(6), SUNDAY(7); /** * @description: 周几的数字表达形式 **/ public final int dayOfWeekValue; private DoTheCookingEnum(int dayOfWeekValue) { this.dayOfWeekValue = dayOfWeekValue; } }
包含了参数,构造器以及周一到周日对应的枚举实例,并使用了Lombok生成了dayOfWeekValue属性的get方法。属性dayOfWeekValue对应的是1-7的条件,接着我们在枚举中定义一个根据dayOfWeekValue参数来获取枚举实例的方法。
/** * @description: 根据dayOfWeekValue来获取不同的枚举 * @author: Vinci * @date: 2024/3/15 13:08 **/ public static DoTheCookingEnum getEnum(int dayOfWeekValue) { for (DoTheCookingEnum doTheCookingEnum : DoTheCookingEnum.values()) { if (doTheCookingEnum.dayOfWeekValue == dayOfWeekValue) { return doTheCookingEnum; } } return null; }
这样我们就可以根据不同的dayOfWeekValue获取到相应的枚举了,接下来的步骤就是重点了,我们在枚举中定义一个抽象方法,作为做菜的行为。
/** * @description: 做菜 * @author: Vinci * @date: 2024/3/15 13:12 **/ public abstract void cooking();
定义了做菜的抽象方法后,我们就可以在每个枚举实例当中去重写cooking()这个抽象方法。
MONDAY(1) { @Override public void cooking() { System.out.println("今天是周一,今天做农家一碗香。"); } }, TUESDAY(2) { @Override public void cooking() { System.out.println("今天是周二,今天做鱼香肉丝。"); } }, WEDNESDAY(3) { @Override public void cooking() { System.out.println("今天是周三,今天做韭菜鸡蛋。"); } }, THURSDAY(4) { @Override public void cooking() { System.out.println("今天是周四,今天做回锅肉。"); } }, FRIDAY(5) { @Override public void cooking() { System.out.println("今天是周五,今天做蛋炒饭。"); } }, SATURDAY(6) { @Override public void cooking() { System.out.println("今天是周六,今天做麻婆豆腐。"); } }, SUNDAY(7) { @Override public void cooking() { System.out.println("今天是周日,今天做土豆丝。"); } };
枚举完整代码如下:
package com.example.demo.enums; import lombok.Getter; /** * @package: com.example.demo.enums * @FileName: DoTheCookingEnum * @author: Vinci * @description: 周几做什么菜 * @date: 2024/3/15 11:42 */ @Getter public enum DoTheCookingEnum { MONDAY(1) { @Override public void cooking() { System.out.println("今天是周一,今天做农家一碗香。"); } }, TUESDAY(2) { @Override public void cooking() { System.out.println("今天是周二,今天做鱼香肉丝。"); } }, WEDNESDAY(3) { @Override public void cooking() { System.out.println("今天是周三,今天做韭菜鸡蛋。"); } }, THURSDAY(4) { @Override public void cooking() { System.out.println("今天是周四,今天做回锅肉。"); } }, FRIDAY(5) { @Override public void cooking() { System.out.println("今天是周五,今天做蛋炒饭。"); } }, SATURDAY(6) { @Override public void cooking() { System.out.println("今天是周六,今天做麻婆豆腐。"); } }, SUNDAY(7) { @Override public void cooking() { System.out.println("今天是周日,今天做土豆丝。"); } }; /** * @description: 周几的数字表达形式 **/ public final int dayOfWeekValue; private DoTheCookingEnum(int dayOfWeekValue) { this.dayOfWeekValue = dayOfWeekValue; } /** * @description: 根据dayOfWeekValue来获取不同的枚举 * @author: Vinci * @date: 2024/3/15 13:08 **/ public static DoTheCookingEnum getEnum(int dayOfWeekValue) { for (DoTheCookingEnum doTheCookingEnum : DoTheCookingEnum.values()) { if (doTheCookingEnum.dayOfWeekValue == dayOfWeekValue) { return doTheCookingEnum; } } return null; } /** * @description: 做菜 * @author: Vinci * @date: 2024/3/15 13:13 **/ public abstract void cooking(); }
枚举定义完成后,我们就可以去调用不同枚举元素来实现不同的逻辑了。
public static void main(String[] args) { //获取今天是周几 LocalDate today = LocalDate.now(); DayOfWeek dayOfWeek = today.getDayOfWeek(); int dayOfWeekValue = dayOfWeek.getValue(); //调用getEnum根据dayOfWeekValue获取枚举对象 DoTheCookingEnum anEnum = DoTheCookingEnum.getEnum(dayOfWeekValue); //执行做菜方法,获取今天做什么菜 if(anEnum != null){ anEnum.cooking(); } }
因为今天是周五,所以今晚做蛋炒饭了:
以上便是策略+枚举来替换掉if-else的方法,这样写代码耦合度变低了,也更加简洁了,扩展性也很强,比如以后有了个星期八,是不是我们只需要,在枚举中再创建一个实例,就不用改代码了。当然还有很多种避免使用if-else的方法,欢迎小伙伴们一起讨论。