1. 提取重复内容到三目元算符中:
修改前:
if (StringUtils.isBlank(request.getAppId())) {if (!request.getComponentAppId().equals(record.getAppId()))) {LOGGER.error("参数异常 请求参数与数据记录不一致,request is {}", request);throw new KsMpPayException(INVALID_REQUEST, "请求参数与数据记录不一致");}} else {if (!request.getAppId().equals(record.getAppId())) {LOGGER.error("参数异常 请求参数与数据记录不一致,request is {}", request);throw new KsMpPayException(INVALID_REQUEST, "请求参数与数据记录不一致");}}
修改后:
String appId = StringUtils.isBlank(request.getAppId()) ? request.getComponentAppId() : request.getAppId();if (!appId.equals(record.getAppId())) {LOGGER.error("参数异常 请求参数与数据记录不一致,request is {}", request);throw new KsMpPayException(INVALID_REQUEST, "请求参数与数据记录不一致");}
2. 使用 Optional:
用 Optional 来封装可能为 null 的值,利用 Optional 提供的一系列方法来处理这个值,避免了显式的 null 判断和繁琐的条件语句。
下面是这个思路的一些关键步骤:
- 识别可能为 null 的值:
- 首先,我们需要找出代码中可能为 null 的值。在你的示例中,这个值是字符串 str。
- 使用 Optional.ofNullable 封装这个值:
- 然后,我们可以使用 Optional.ofNullable 方法来封装这个值。这个方法会返回一个 Optional 对象,如果原始值不为 null,则 Optional 对象中包含这个值,否则 Optional 对象为空。
- 使用 Optional 的方法处理这个值:
- 接下来,我们可以使用 Optional 的一些方法来处理这个值。如果这个值存在(即不为 null),我们可以使用 Optional 的 ifPresent 或者 ifPresentOrElse 方法来对这个值进行操作。如果这个值不存在(即为 null),我们可以使用 Optional 的 orElse、orElseGet 或者 ifPresentOrElse 方法来提供一个默认值或者执行一个默认操作。
下面我们通过一个 Spring Boot 的实例来具体说明这个思路:
例如,我们可能需要从一个 UserRepository 中查询用户,然后打印出用户名。未优化的代码可能会这样写:
String username = userRepository.findUsernameById(id);
if (username != null) {System.out.println(username);
} else {System.out.println("User not found");
}
使用 Optional 进行优化后的代码可以这样写:
Optional<String> username = userRepository.findUsernameById(id);username.ifPresentOrElse(System.out::println, () -> System.out.println("User not found"));
这样,我们就不再需要显式地检查用户名是否为 null,代码更加简洁、易读,并且更能表达出我们的意图:如果用户名存在,打印出用户名,否则打印出 "User not found"。
3. 表驱动法:
表驱动法的主要思路是:
将逻辑条件与具体操作映射到一个表(如:哈希映射表)中,然后直接从表中获取和执行相应的操作,避免了复杂的条件语句。
以下是这种方法的关键步骤:
- 创建映射表:
- 首先创建一个映射表,表中的键为原先的逻辑条件,值为相应的操作。
- 初始化映射表:
- 对映射表进行初始化,将所有的逻辑条件与相应的操作放入表中。
- 使用映射表:
- 在需要执行操作的地方,使用映射表。根据当前的条件从表中获取相应的操作,然后执行该操作。
这种方式的优势在于它可以将复杂的条件逻辑简化为从映射表中获取和执行操作,提高了代码的可读性和可维护性。
下面我们通过一个 Spring Boot 的实例来具体说明这个思路:
假设我们有一个需求:根据用户的角色进行不同的操作。
优化前的代码可能会像这样:
if ("admin".equals(role)) {doAdminAction(user);} else if ("user".equals(role)) {doUserAction(user);} else if ("guest".equals(role)) {doGuestAction(user);}
使用表驱动法进行优化后的代码可以是这样的:
Map<String, Consumer<User>> roleActionMappings = new HashMap<>();// 初始化映射表roleActionMappings.put("admin", this::doAdminAction);roleActionMappings.put("user", this::doUserAction);roleActionMappings.put("guest", this::doGuestAction);// 使用映射表roleActionMappings.get(role).accept(user);
在这个例子中,我们首先创建了一个映射表 roleActionMappings,表中的键为用户的角色,值为相应的操作。然后我们对映射表进行初始化。最后,在需要执行操作的地方,我们从映射表中获取并执行相应的操作,避免了复杂的条件语句。
4. 使用枚举(表驱动法的一种):
枚举类型是一种特殊的 Java 类型,用来定义一个固定数量的常量。在这个案例中,每个订单状态对应一个枚举常量。
这种优化的基本思路如下:
- 确定枚举常量:
- 你首先要确定你需要的枚举常量。在你的例子中,这些常量是订单的各种状态。
- 定义枚举类型:
- 然后你需要定义一个枚举类型,包含上面确定的所有枚举常量。每个枚举常量都可以有一个或多个属性,这些属性可以用来存储与该枚举常量相关的信息。在你的例子中,每个订单状态有一个对应的描述。
- 使用枚举类型替代条件逻辑:
- 最后,你可以用枚举类型来替代原来的条件逻辑。在你的例子中,你只需要调用枚举类型的 of 方法,然后根据返回的枚举常量获取相应的订单状态描述。
下面我们通过一个 Spring Boot 的实例来具体说明这个思路:
例如,我们可以定义一个表示用户角色的枚举类型,然后用这个枚举类型来替代原来的条件逻辑。我们可以用以下的枚举类型:
public enum Role {ADMIN("管理员"), USER("用户"), GUEST("访客");private final String description;Role(String description) {this.description = description;}public String getDescription() {return description;}}
然后我们可以根据用户的角色来进行不同的操作,而不需要使用复杂的条件逻辑。例如,我们可以这样做:
String roleDescription = user.getRole().getDescription();
以上,就是使用枚举简化条件逻辑的基本思路和应用方法。使用枚举可以使代码更加简洁、易读,并且可以提供更好的类型安全。
5. 策略模式 + 工厂方法:
"策略模式 + 工厂方法"这种优化方式的思路主要是将不同的逻辑行为抽象出来,放在不同的策略实现类中,并通过工厂方法获取对应的实例,以此来消除复杂的条件语句。
以下是具体步骤:
- 定义策略接口:
- 首先定义一个策略接口,接口中声明需要实现的行为。
- 实现策略接口:
- 针对每种可能的条件,实现策略接口,完成相应的逻辑。
- 建立策略工厂:
- 定义一个工厂类,用于根据条件获取对应的策略实现。
- 使用策略工厂:
- 在需要的地方,使用策略工厂根据条件获取策略实现并执行。
现在我们以一个Spring Boot的实例来说明这个思路。
假设我们有一个需求:根据用户角色执行不同的动作。
优化前的代码可能如下:
public void doAction(String role) {if ("admin".equals(role)) {System.out.println("Admin action");} else if ("user".equals(role)) {System.out.println("User action");} else if ("guest".equals(role)) {System.out.println("Guest action");}}
优化后的代码:
首先,定义策略接口:
public interface RoleAction {void action();}
然后,对于每种角色,分别实现策略接口:
public class AdminAction implements RoleAction {@Overridepublic void action() {System.out.println("Admin action");}}public class UserAction implements RoleAction {@Overridepublic void action() {System.out.println("User action");}}public class GuestAction implements RoleAction {@Overridepublic void action() {System.out.println("Guest action");}}
接着,定义工厂类:
public class RoleActionFactory {private static final Map<String, RoleAction> roleActionMap = new HashMap<>();static {roleActionMap.put("admin", new AdminAction());roleActionMap.put("user", new UserAction());roleActionMap.put("guest", new GuestAction());}public static RoleAction getRoleAction(String role) {return roleActionMap.get(role);}}
最后,在需要的地方,使用工厂类获取策略实现并执行:
public void doAction(String role) {RoleAction action = RoleActionFactory.getRoleAction(role);if (action != null) {action.action();}}
在优化后的代码中,我们根据角色定义了不同的策略实现,然后通过工厂方法获取相应的实现,执行相应的操作,消除了条件语句。
6. Map+函数式接口:
"Map + 函数式接口" 的优化方式是通过使用 Java 8 的新特性,Lambda 表达式,实现条件代码的优化。这种方式的关键点在于将条件判断作为 Map 的 key,将执行的动作封装成函数接口,作为 Map 的 value。通过这种方式,我们可以实现高效的条件分支查找,避免了传统的 if-else 或 switch-case 语句。
以下是具体步骤:
- 定义函数式接口:
- Java 8 中的函数式接口允许我们将行为作为参数传递,这就意味着我们可以定义一个接口来表示我们的操作。
- 使用 Map 存储条件和对应的行为:
- 在这个 Map 中,key 是条件,value 是对应的行为(函数式接口的实例)。
- 初始化 Map:
- 在服务启动的时候(或者在需要的时候),我们需要初始化这个 Map,将所有可能的条件和对应的行为填充进去。
- 使用 Map 进行条件判断和操作:
- 当需要进行条件判断的时候,我们只需要根据条件从 Map 中取出对应的行为(函数式接口的实例),然后执行即可。
现在我们以一个Spring Boot的实例来说明这个思路。
假设我们有一个需求:根据不同类型的用户,打印出不同的欢迎信息。
优化前的代码可能如下:
public void welcome(String userType) {if ("admin".equals(userType)) {System.out.println("Welcome, admin!");} else if ("user".equals(userType)) {System.out.println("Welcome, user!");} else if ("guest".equals(userType)) {System.out.println("Welcome, guest!");} else {System.out.println("Welcome!");}}
优化后的代码:
首先,定义一个函数式接口:
@FunctionalInterfacepublic interface WelcomeAction {void action();}
然后,使用 Map 存储条件和对应的行为:
private static final Map<String, WelcomeAction> welcomeActionMap = new HashMap<>();static {welcomeActionMap.put("admin", () -> System.out.println("Welcome, admin!"));welcomeActionMap.put("user", () -> System.out.println("Welcome, user!"));welcomeActionMap.put("guest", () -> System.out.println("Welcome, guest!"));}
最后,在需要的地方,根据条件从 Map 中取出对应的行为并执行:
public void welcome(String userType) {WelcomeAction action = welcomeActionMap.get(userType);if (action != null) {action.action();} else {System.out.println("Welcome!");}}
在优化后的代码中,我们使用了 Map 和函数式接口来管理和执行不同的行为,大大减少了条件语句的使用,使代码更简洁,更易读。