← Назад к вопросам

Как избежать большого количества проверок с помощью if?

2.0 Middle🔥 141 комментариев
#Основы Java

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Избегание множественных if-проверок

Много вложенных if-ов делают код сложным для чтения и поддержки. Вот проверенные подходы, которые я использовал в боевых проектах.

1. Ранний return (Guard Clauses)

Проблема:

public String processUser(User user) {
  if (user != null) {
    if (user.isActive()) {
      if (user.hasPermission("ADMIN")) {
        return user.getName();
      } else {
        return "No permission";
      }
    } else {
      return "User not active";
    }
  } else {
    return "User is null";
  }
}

Решение: Guard Clauses

public String processUser(User user) {
  if (user == null) return "User is null";
  if (!user.isActive()) return "User not active";
  if (!user.hasPermission("ADMIN")) return "No permission";
  
  return user.getName();
}

Основная логика видна сразу, исключения обработаны в начале.

2. Switch выражения (Java 14+) вместо if-else цепочки

Проблема:

if (status == Status.PENDING) {
  return "Ожидание";
} else if (status == Status.APPROVED) {
  return "Одобрено";
} else if (status == Status.REJECTED) {
  return "Отклонено";
} else {
  return "Неизвестный статус";
}

Решение: Switch Expression

String message = switch (status) {
  case PENDING -> "Ожидание";
  case APPROVED -> "Одобрено";
  case REJECTED -> "Отклонено";
  default -> "Неизвестный статус";
};

Краще, чище, безопаснее (compiler проверит все case-ы).

3. Sealed Classes для контроля иерархии

public sealed class PaymentMethod permits CreditCard, PayPal, ApplePay {}

public final class CreditCard extends PaymentMethod {}
public final class PayPal extends PaymentMethod {}
public final class ApplePay extends PaymentMethod {}

String process = switch (payment) {
  case CreditCard card -> processCard(card);
  case PayPal pp -> processPayPal(pp);
  case ApplePay ap -> processApple(ap);
};

4. Паттерны (Java 17+)

if (obj instanceof String str) {
  return str.length();
}

String result = switch (obj) {
  case String s -> "String: " + s.length();
  case Integer i -> "Integer: " + i;
  case null -> "null";
  default -> "Unknown";
};

5. Стратегия (Strategy Pattern)

public interface DiscountStrategy {
  double getDiscount();
}

public class GoldDiscount implements DiscountStrategy {
  @Override
  public double getDiscount() { return 0.2; }
}

public class PricingService {
  private final Map<String, DiscountStrategy> strategies = Map.of(
    "GOLD", new GoldDiscount(),
    "SILVER", new SilverDiscount(),
    "BRONZE", new BronzeDiscount()
  );
  
  public double applyDiscount(String type, double price) {
    return price * (1 - strategies.get(type).getDiscount());
  }
}

6. Optional вместо null-проверок

Проблема:

if (user != null && user.getAddress() != null && user.getAddress().getCity() != null) {
  return user.getAddress().getCity();
}

Решение: Optional

String city = Optional.ofNullable(user)
  .map(User::getAddress)
  .map(Address::getCity)
  .orElse("Unknown");

7. Полиморфизм

public interface Notification {
  void send();
}

for (Notification notification : notifications) {
  notification.send();
}

8. Conditional Builder Pattern

public class QueryBuilder {
  private List<String> conditions = new ArrayList<>();
  
  public QueryBuilder when(boolean condition, String clause) {
    if (condition) {
      conditions.add(clause);
    }
    return this;
  }
}

String query = new QueryBuilder()
  .when(hasEmail, "email = 'test@example.com'")
  .when(hasAge, "age > 18")
  .build();

Практический пример: Валидация

До:

public boolean validate(User user) {
  if (user == null) return false;
  if (user.getEmail() == null || user.getEmail().isEmpty()) return false;
  if (!user.getEmail().contains("@")) return false;
  if (user.getAge() == null || user.getAge() < 18) return false;
  return true;
}

После:

public boolean validate(User user) {
  return Optional.ofNullable(user)
    .filter(u -> isValidEmail(u.getEmail()))
    .filter(u -> isAdult(u.getAge()))
    .isPresent();
}

private boolean isValidEmail(String email) {
  return email != null && email.contains("@");
}

private boolean isAdult(Integer age) {
  return age != null && age >= 18;
}

Итог

✅ Guard clauses для раннего выхода ✅ Switch expressions вместо if-else ✅ Optional для работы с null ✅ Полиморфизм вместо type-checking ✅ Strategy pattern для разной логики по типам

Чем больше используешь эти техники — тем чище и понятнее становится код. А понятный код проще тестировать и поддерживать.

Как избежать большого количества проверок с помощью if? | PrepBro