가끔 누군가의 코드를 보면 if-else문으로 가득차게 쓴 걸 봅니다. 이렇게 되어있는 코드는 동료들이 정확한 의도를 알게 하기 어렵습니다.
코드는 가독성이 있게 짜는게 매우매우 중요한데요.
가독성을 높이기 위한 첫번째로는 if-else문을 코드에서 최대한 지우는 것입니다.
이번 포스팅은 효율적으로 if-else문 코드를 제거하여 코드의 가독성을 올리고 개선할 수 있는 방법들을 말씀드리려고 합니다.
다음과 같은 코드가 있습니다.
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를 제거할 수 있습니다.
다음과 같은 코드가 있다고 가정해봅시다.
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는 굉장히 괜찮은 대안일 될 것 입니다.
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);
}
마지막 방법인 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