냄새 12. 반복되는 Switch 문

    들어가기 전

    이 글은 인프런 백기선님의 강의를 복습하며 작성한 글입니다. 


    냄새 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을 반환한다. 자바에서 스위치 문으로 진입하게 되면, 다음 두 가지 조건 중 하나를 만족할 때 까지 진행된다.

    1. 스위치 문의 끝까지 수행한다. 
    2. 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;
            };
        }
    }
    

    댓글

    Designed by JB FACTORY