210219_B책_switch 실패 피하기

정재현·2021년 2월 19일
0

TIL

목록 보기
71/80

어제의 NullPointer에 이어서 오늘은 switch 실패에 대해 알아본다.
예제 코드를 바로 보자면,

CruiseControl cruiseControl;

void authorize(User user) {
	Objects.requireNonNull(user);
    switch (user.getRank()) {
      case UNKOWN:
          cruiseControl.logUnauthorizedAccessAttempt();
      case ASTROANUT:
          cruiseControl.grantAccess(user);
          break;
      case COMMANDER:
          cruiseControl.grantAccess(user);
          cruiseControl.grantAdminAccess(user);
          break;
          }
	}
}

switch 문을 사용할 때는 항상 주의해야 할 점이 있다.
위 코드의 authorize()는 매개변수를 검증하고 null 참조를 확인한다.
java API에 있는 편리한 매개변수 검증 방법 Objects.requireNonNull() 을 사용해 입력이
null이면 예외를 발생시킵니다. 하지만 위 코드에는 결정적인 버그가 남아있는데
버그는 첫번째 case에서 break을 빼먹었다는 점.
(일부러 break을 빼고 사용하는 의도로 사용할 수도 있지않나? 물론 위 코드에서는 아니겠지만..
==> 간혹 의도적으로 break을 빼고 사용하는 것이라면 반드시 주석을 남겨야 한다!)

switch는 이러한 동작으로 악명이 높다고 한다.
break문 또는 블록 끝에 다다라야 실행을 멈추기 때문.
이번 챕터는 버그 고치기가 매우 쉽다. 그냥 빼먹은 break문을 붙이면 끝!

하지만.. 문제는.. 과연 switch가 정말 가장 완벽한 대안이냐? 라는 것이다.
위 예제 코드에서 switch는 분리해야 할 두가지 관심사를 섞고 있다.
(허가받지 않은 접근과 허가된 접근을 하나의 코드 블록으로 놨다.)
지은이의 관심상 서로 다른 관심사는 서로 다른 코드 블록에 넣어야 한다고 한다.
이 내용은 1.8챕터 <코드 대칭 이루기>에서 진행할 예정이다.

나눴을 때의 이점은
1. 코드가 읽기 더 쉬워진다.
2. 스위치 실패와 같은 우연한 버그가 발생할 확률이 적다.

(항상 강조하는 것이지만 상대방이 코드를 보고 이 코드는 뭐지? 라는 생각이 안들게끔 의도하는 것이 중요하다고 생각)
그런데 switch로는 관심사를 분리하기가 어렵다.
그래서 if문을 사용하는 방법을 선호한다고.. (같은 팀원분도 이렇게 똑같이 말씀하신게 머릿속에 확 지나간다.)

오늘의 코멘트: 오늘은 뭔가 버그같지 않은 버그..

profile
"돈받고 일하면 프로다"

0개의 댓글