자바 코드에서 if-else문 우아하게 지우는 방법

Jiwon Jung·2024년 1월 21일
1
post-thumbnail
post-custom-banner

가끔 누군가의 코드를 보면 if-else문으로 가득차게 쓴 걸 봅니다. 이렇게 되어있는 코드는 동료들이 정확한 의도를 알게 하기 어렵습니다.

코드는 가독성이 있게 짜는게 매우매우 중요한데요.

가독성을 높이기 위한 첫번째로는 if-else문을 코드에서 최대한 지우는 것입니다.

이번 포스팅은 효율적으로 if-else문 코드를 제거하여 코드의 가독성을 올리고 개선할 수 있는 방법들을 말씀드리려고 합니다.

옵션1. Early return

다음과 같은 코드가 있습니다.

public boolean isValid(String condition) {
  boolean result;
  if (condition != null){
      if (condition.equals("hi") {
        result = true;
      } else {
         result = false;
      }
  } else {
    result= false;
  }
  return result;
}

위 코드를 Early Return (조기반환)원칙으로 써본다면 아래와 같습니다.
반환을 바로바로 하며, 불필요한 else를 제거하는 것입니다.

public boolean isValid(String condition) {
  if (condition == null) {
    return false;
  }

  if (condition.equals("hi") {
    return true
  }

  return false;
}

이러한 방법은 보통 심플한 구조에서 적합하고 조기 반환을 함으로써 불필요한 if-else를 제거할 수 있습니다.

옵션2.Enumeration (열거)

다음과 같은 코드가 있다고 가정해봅시다.

public String getLabel(int status) {
    String label;
    if (1 == status) {
        label = "Padding";
    } else if (2 == status) {
        label = "Paid";
    } else if (3 == status) {
        label = "Success";
    } else if (4 == status) {
        label = "Failed";
    }
    return label;
}

이렇게 사용하는 코드 스타일이 흔하지 않을 것 같다고 말할수도 있겠지만 상당히 흔하게 찾아볼수 있었습니다.

따라서 위 코드와 같이 열거형(enumeration) 스타일을 개선하기 위해 enum 을 적극 활용하여 아래처럼 개선해볼 수 있습니다.

@Getter
@AllArgsConstructor
public enum StatusLabelEnum {
    Padding(1, "Padding"),
    Paid(2, "Paid"),
    Success(3, "Success"),
    Failed(4, "Failed"),
    ;

    private int status;
    private String label;

    public static String getLabelByStatus(int status) {
        for (StatusLabelEnum labelEnum : StatusLabelEnum.values()) {
            if (labelEnum.getStatus() == status) {
                return labelEnum.getLabel();
            }
        }
        return "Unknown";
    }
}

위와 같이 enum에 정의를 해둔다면, 위에서 본것처럼 if-else if-else 구조로 쓰는게 아니라 다음과 같이 한줄의 코드로 최적화가 가능합니다!

public String getLabel(int status) {
  return StatusLabelEnum.getLabelByStatus(status);
}

당연히 이 방법이 무조건 먹히는 방법은 아니겠지만 적어도 결과값이 Paid, Success, Failed와 같이 정해져있다면 Option2는 굉장히 괜찮은 대안일 될 것 입니다.

Option3. Optional

Java8에서 Optional이 등장했지만 여전히 많은 프로젝트들을 보다보면 null를 위해 다음과 같은 if-else문을 많이 사용하는 것을 볼 수 있습니다.

public int getOrderStatus(UUID id) {
  Order order = getOrderById(id);
  if (order == null) {
      return 1;
  } else {
      return order.getOrderStatus();
  }
}

위와 같은 경우는 Optional을 활용하여 상당히 우아하게 개선해볼 수 있습니다.

public int getOrderStatus(UUID id) {
  Order order = getOrderById(id);
  return Optional.ofNullable(order).map(Order::getOrderStatus).orElse(1);
}

Option4. Table-driven Method

마지막 방법인 table-driven method도 과한 if-else를 사용하지 않고도 원하는 정보를 찾을 수 있도록 하는 방법인데요. 우선 아래와 같은 코드가 있다고 가정해 봅시다.

if ("code1".equals(action)) {
    doAction1();
} else if ("code2".equals(action)) {
    doAction2();
} else if ("code3".equals(action)) {
    doAction3();
} else if ("code4".equals(action)) {
    doAction4();
} else if ("code5".equals(action)) {
    doAction5();
}

위와 같은 코드를 table-driven method로 사용하여 다음과 같이 사용 가능합니다!

//Definition
Map<String, Function<?> action> actionMap = new HashMap<>();
action.put("code1",() -> doAction1());
action.put("code2",() -> doAction2());
action.put("code3",() -> doAction3());
action.put("code4",() -> doAction4());
action.put("code5",() -> doAction5());

//use case
actionMap.get(action).apply();

사실 위 방법도 있지만, 아래처럼 interface를 활용해 좀 더 우아하게 개선해볼 수 있습니다.

//1. Define interface
public interface ActionService {
    void doAction();
}

//2. Define implementations
public class ActionService1 implements ActionService{
    public void doAction() {
        //do something
    }
}

//3. add to table
Map<String, ActionService> actionMap = new HashMap<>();
action.put("code1",new ActionService1());
action.put("code2",new ActionService2());
action.put("code3",new ActionService3());
action.put("code4",new ActionService4());
action.put("code5",new ActionService5());

//4. use it
actionMap.get(action).doAction();

위 4가지 방법이 조금이나마 if-else문을 제거하는데 도움되었으면 좋겠습니다.
감사합니다!


Reference
https://medium.com/@malvin.lok/how-to-elegantly-remove-if-else-in-your-java-code-27b2393544ae

profile
게을러지고 싶어 부지런한 개발자
post-custom-banner

0개의 댓글