냄새 12. 반복되는 Switch 문
- etc/리팩토링
- 2023. 5. 10.
들어가기 전
이 글은 인프런 백기선님의 강의를 복습하며 작성한 글입니다.
냄새 12. 반복되는 Switch문(Repeated Switched)
- 반복되는 Switch문 냄새
- 예전에는 Switch 문이 한번만 등장해도 코드 냄새로 생각하고 다형성 적용을 권장했다.
- 최근에는 여러 프로그래밍 언어에서 보다 세련된 형태의 스위치 문을 지원하고 있다.
- 따라서 오늘 날은 '반복해서 등작하는 동일한 스위치 문'을 냄새로 여기고 있다.
- 반복되는 Switch문 단점
- 반복해서 동일한 스위치 문이 나타난다면, 새로운 조건 추가/ 기존 조건 변경 시, 모든 스위치 문을 찾아서 코드를 고쳐야 할 지도 모른다.
- 리팩토링 방법
- 스위치 익스프레션으로 변경 (스위치 문에 비해 가독성 증가)
- 조건문 / Switch문을 다형성으로 리팩토링
동일한 스위치문이 여기저기서 반복되서 나타난다면, 이곳은 '반복되는 Switch문'이라는 냄새다. 이 냄새는 리팩토링을 통해 해결해야한다. 예를 들면 이런 형태가 '반복되는 스위치 문'이 될 것이다.
// 동일한 스위치문이 코드 여러곳에서 사용됨.
public class A {
void B(){
Switch
case A: ...
case B: ...
case C: ...
}
}
public class B {
void C(){
Switch
case A: ...
case B: ...
case C: ...
}
}
코드
이 코드에서는 다형성으로 변경하는 리팩토링을 보여주는 것은 아니다. 아래 코드에서 발생할 수 있는 스위치문의 문제와 이유, 그리고 Improve 할 수 있는 방법에 대해서 설명하고자 한다.
아래 코드의 스위치 문은 중대한 문제를 가지고 있다. 개발자가 작성한 의도와는 다르게 해당 코드는 항상 0을 반환한다. 자바에서 스위치 문으로 진입하게 되면, 다음 두 가지 조건 중 하나를 만족할 때 까지 진행된다.
- 스위치 문의 끝까지 수행한다.
- break를 만날 때까지 수행한다.
아래에서는 break가 없기 때문에 해당 메서드는 항상 default 절까지 진행되게 되며, 그 결과 항상 0을 반환하게 되어서 의도한 대로 동작하지 않게 된다.
public class SwitchImprovements {
public int vacationHours(String type) {
int result;
switch (type) {
case "full-time": result = 120;
case "part-time": result = 80;
case "temporal": result = 32;
default: result = 0;
}
return result;
}
}
코드 수정1 : break문 추가
스위치 문에 Break 키워드가 없어서 항상 끝까지 진행된다는 문제점이 있었다. 이것은 분명한 버그다. 따라서 이것을 해결하기 위해 다음과 같이 break 키워드를 각 스위치 문의 조건에 넣어줄 수 있다. 이렇게 하면 해당 버그를 처리할 수 있다.
public class SwitchImprovements {
// break가 없기 때문에 항상 0만 반환된다.
public int vacationHours(String type) {
int result;
switch (type) {
case "full-time": result = 120; break;
case "part-time": result = 80; break;
case "temporal": result = 32; break;
default: result = 0;
}
return result;
}
}
코드 수정 2 : 향상된 스위치문 (Switch Expression)으로 리팩토링
현재 존재하고 있던 Switch문을 Break문을 반복적으로 표기해줘야 한다는 단점이 있었다. 이런 스위치 문의 개선된 버전인 스위치 익스프레션이 존재한다. 스위치 익스프레션을 이용하면 아래와 같이 표현해 줄 수 있게 된다. Break문이 없어져서 더욱 직관적으로 코딩을 할 수 있게 되고, 실수할 여지도 많이 줄어든다.
public class SwitchImprovements {
// break가 없기 때문에 항상 0만 반환된다.
public int vacationHours(String type) {
int result = switch (type) {
case "full-time" -> 120;
case "part-time" -> 80;
case "temporal" -> 32;
default -> 0;
};
}
}
'etc > 리팩토링' 카테고리의 다른 글
냄새14. 성의없는 요소 (1) | 2023.05.10 |
---|---|
냄새 13. 반복문 (0) | 2023.05.10 |
리팩토링 33. 반복문을 파이프라인으로 바꾸기 (0) | 2023.05.10 |
리팩토링 32. 조건부 로직을 다형성으로 바꾸기 (0) | 2023.05.10 |
리팩토링 31. 타입 코드를 서브클래스로 바꾸기 (0) | 2023.05.10 |