클린코드를 읽고 항상 미뤄만 두던 글 독후감
코드를 작성하다보면 여러 조건문을 작성하게 되는 경우가 있어 기록으로 남겨보았습니다.
배달앱을 운영하는 개발자라고 가정해봅시다.
다음 3가지 조건일 경우, 리뷰 작성이 불가능하게 해달라고 요청이 왔습니다.
1. `주문완료`가 아닌 경우
2. `주문접수` 이면서, `배달중`이 아닌 경우
3. `주문접수` 이면서, `배달완료`가 아닌 경우
요청에 따라 코드를 작성해봅니다.
주문은 주문접수
, 주문완료
배달은 배달전
, 배달중
, 배달완료
의 경우만 고려해봅시다.
public class Main {
final static String ORD_STS_010 = "10"; // 주문접수
final static String ORD_STS_020 = "20"; // 주문완료
final static String DELIVERY_STS_010 = "10"; // 배달 전
final static String DELIVERY_STS_020 = "20"; // 배달 증
final static String DELIVERY_STS_030 = "30"; // 배달 완료
public static void main(String[] args) throws Exception{
String ordStsCd = args[0]; // 주문상태코드
String delivStsCd = args[1]; // 배달상태코드
// '주문완료'가 아니거나, '주문접수'이면서 ('배달중' 또는 '배달완료')가 아닌 경우 리뷰작성이 불가능합니다.
if (!(ordStsCd.equals(ORD_STS_020)
|| (ordStsCd.equals(ORD_STS_010) && (delivStsCd.equals(DELIVERY_STS_020) || delivStsCd.equals(DELIVERY_STS_030)))
)) {
throw new Exception("리뷰 작성이 불가능합니다");
}
// 리뷰 작성 로직..
System.out.println("완전 맛있어요!");
System.out.println("리뷰 작성이 완료되었습니다");
}
}
주문접수 + 배달 전에는 리뷰 작성이 불가능하며,
ordStsCd = '10', delivStsCd = '10' 인 경우를 제외하고 모두 리뷰 작성이 가능한 걸 확인했습니다.
하지만, 위 코드의 조건문을 주석없이 한 눈에 보기란 쉽지 않습니다.
if (!(ordStsCd.equals(ORD_STS_020)
|| (ordStsCd.equals(ORD_STS_010) && (delivStsCd.equals(DELIVERY_STS_020) || delivStsCd.equals(DELIVERY_STS_030)))
))
위 코드를 클린 코드로 고쳐봅시다.
클린코드
를 읽다보면 여러 가지 클린 코드 작성 방법이 등장합니다.
그 중 3가지를 활용해봅시다.
1. 조건을 캡슐화하라 : 조건의 의도를 분명히 밝히기
65세 이상 시민이 무료 승차권을 받을 요건이 되는 지 검사한다
// 나쁜예
if ((person.age >= 65) && (person.hasWelfareCard) && (person.home == "HERE"))
// 좋은 예
if ((person.isEligibleForFreeTicket()))
2. 부정조건문을 지양하라
// 나쁜 예
if (!this.isPositiveEffect)
// 좋은 예
if (this.isNegativeEffect)
3. 서술적인 이름을 사용하라
// 함수가 작고 단순할수록 서술적인 이름을 작성하기 쉽다
// 서술적인 이름을 사용하면 보는 사람도 설계가 뚜렷해지고 코드를 개선하기 쉬워진다
public void includeSetupAndTeardownPages()
위 3가지를 고려하여 코드를 고쳐봅시다
public class Main2 {
final static String ORD_STS_010 = "10"; // 주문접수
final static String ORD_STS_020 = "20"; // 주문완료
final static String DELIVERY_STS_010 = "10"; // 배달 전
final static String DELIVERY_STS_020 = "20"; // 배달 증
final static String DELIVERY_STS_030 = "30"; // 배달 완료
public static void main(String[] args) throws Exception{
String ordStsCd = args[0];
String delivStsCd = args[1];
// 1. 조건을 캡슐화하라
isReviewableOrThrow(ordStsCd, delivStsCd);
// 리뷰 작성 로직..
System.out.println("완전 맛있어요!");
System.out.println("리뷰 작성이 완료되었습니다");
}
// 2. 부정조건문을 지양하라
// 3. 서술적인 이름을 사용하라
static void isReviewableOrThrow(String ordStsCd, String delivStsCd) throws Exception{
// '주문완료'
if(ORD_STS_020.equals(ordStsCd)) return;
// '주문접수' + '배달중'
if(ORD_STS_010.equals(ordStsCd) && DELIVERY_STS_020.equals(delivStsCd)) return;
// '주문접수' + '배달완료'
if(ORD_STS_010.equals(ordStsCd) && DELIVERY_STS_030.equals(delivStsCd)) return;
// 위에서 return 되지 않았다면 리뷰작성이 불가능한 상태
throw new Exception("리뷰작성이 불가능합니다");
}
}