如何清理代码中重复的If语句?附注册表单与预订场景示例
优化大量If语句的方案
针对你提供的两段代码,下面给出具体的优化思路和实现:
一、注册表单验证代码优化
原代码多次重复检查用户存在性,条件判断冗余,可通过逻辑整合与方法封装提升可读性和维护性。
优化思路
- 合并存在性检查逻辑,避免重复判断
- 将验证逻辑封装为独立方法,提高复用性
优化后代码
// 提取独立的用户唯一性验证方法 private void validateUniqueUser(User user) { boolean usernameExists = userRepo.findByUsername(user.getUsername()) != null; boolean emailExists = userRepo.findUserByEmail(user.getEmail()) != null; if (usernameExists && emailExists) { throw new AccountException("Email and username already exist"); } else if (usernameExists) { throw new AccountException("Username already exist"); } else if (emailExists) { throw new AccountException("Email already exist"); } } // 业务逻辑中直接调用验证方法 validateUniqueUser(user);
额外优化建议:可在Repository层新增方法existsByUsernameOrEmail(String username, String email),合并两次数据库查询,减少IO开销。
二、预订条件检查代码优化
原代码四个分支存在大量重复逻辑,如全天预订冲突检查在多个分支重复,可通过枚举分类、提取公共方法消除冗余。
优化思路
- 用枚举定义时间段类型,替代多分支判断
- 提取公共验证逻辑为独立方法,避免代码复制
- 提前处理非法输入(未选择时间段),减少嵌套层级
优化后代码
首先定义时间段枚举:
private enum ReservationTimeSlot { FULL_DAY, MORNING, AFTERNOON, NONE } // 提取获取时间段的方法 private ReservationTimeSlot getTimeSlot(ReservationDto reservationDto) { boolean isMorning = reservationDto.isMorning(); boolean isAfternoon = reservationDto.isAfternoon(); if (isMorning && isAfternoon) { return ReservationTimeSlot.FULL_DAY; } else if (isMorning) { return ReservationTimeSlot.MORNING; } else if (isAfternoon) { return ReservationTimeSlot.AFTERNOON; } else { return ReservationTimeSlot.NONE; } } // 提取公共的全天预订冲突检查 private void checkFullDayConflict(Reservation mappedReservation, String date) { int dailyReservations = reservationRepo.existsReservationForDay(mappedReservation.getUsername(), mappedReservation.getDate()); if (dailyReservations > 0) { throw new ServiceException(RESERVATION_MSG + FOR_FULL_DAY + date); } } // 优化后的预订条件检查方法 public void addConditions(ReservationDto reservationDto) { long roomId = roomService.findRoomByRoomName(reservationDto.getRoomName()).getRoomId(); int roomCapacity = roomService.findRoomByRoomId(roomId).getCapacity(); boolean maxCapacityMorning = roomCapacity <= getNumberOfReservationsForRoomByDateVoormiddag(roomId, reservationDto.getDate()); boolean maxCapacityAfternoon = roomCapacity <= getNumberOfReservationsForRoomByDateNamiddag(roomId, reservationDto.getDate()); capacityConditions(reservationDto, maxCapacityMorning, maxCapacityAfternoon); Reservation mappedReservation = mapReservationDto(reservationDto); ReservationTimeSlot timeSlot = getTimeSlot(reservationDto); // 提前处理未选择时间段的非法情况 if (timeSlot == ReservationTimeSlot.NONE) { throw new ServiceException("Selecteer een tijdstip voor uw reservatie"); } // 执行公共的全天冲突检查 checkFullDayConflict(mappedReservation, reservationDto.getDate()); // 根据时间段执行对应验证 switch (timeSlot) { case FULL_DAY: if (reservationRepo.existsReservationForMorning(mappedReservation.getUsername(), mappedReservation.getDate()) > 0 || reservationRepo.existsReservationForAfterNoon(mappedReservation.getUsername(), mappedReservation.getDate()) > 0) { throw new ServiceException(RESERVATION_MSG + "in de voor- of namiddag."); } break; case MORNING: if (reservationRepo.existsReservationForMorning(mappedReservation.getUsername(), mappedReservation.getDate()) > 0) { throw new ServiceException(RESERVATION_MSG + "in de voormiddag."); } break; case AFTERNOON: if (reservationRepo.existsReservationForAfterNoon(mappedReservation.getUsername(), mappedReservation.getDate()) > 0) { throw new ServiceException(RESERVATION_MSG + "in de namiddag"); } break; } }
进一步扩展优化
若后续需新增更多时间段或验证规则,可采用策略模式:
- 定义
ReservationValidationStrategy接口,包含validate方法 - 为每个时间段实现对应策略类(如
FullDayValidation、MorningValidation) - 用工厂类根据时间段获取对应策略并执行验证
这种方式完全消除分支判断,符合开闭原则,新增规则只需添加新策略类即可。
通用优化原则
- 提取重复逻辑:将多次出现的判断、操作封装为独立方法,减少代码冗余
- 提前处理非法情况:把易判断的错误条件放在前面,降低代码嵌套层级
- 用枚举/多态替代分支:多分支场景下,枚举或策略模式可提升扩展性
- 减少重复IO操作:合并重复的数据库查询、外部调用,提升性能
内容的提问来源于stack exchange,提问作者Elias
相关产品推荐
相关产品推荐

