[내일배움캠프] 계산기 구현 - level.04

2024. 9. 10. 18:46내일배움캠프

 이번에 구현한 'Level04 계산기' 는 개인적으로 추가 기능을 반영하기 위해 구현하였다. 내가 반영하고자 하는 것은 바로 Exception 의 활용에 대한 부분인데 해당 부분을 반영하고자 한 이유는 현재 구현된 일부 메서드들이 2개 이상의 기능을 수행한다는 점 그리고 필요에 의해 구현했지만 'boolean' 을 반환하는 메서드를 비교적 자주 구현/사용한다는 점이다.

둘 이상의 기능을 수행하고 다소 복잡해 단숨에 파악하기 힘든 메서드

 

위 이미지의 메서드는 'level03/validation/ValidInput.validCalculation()' 메서드이다. 해당 메서드에 부여한 주 역할은 입력 값의 유효성을 검증하는 것인데, 현재 '검증' 뿐만 아니라 '출력' 도 같이 수행하고 있다. 그리고 메서드의 반환 타입이 boolean 인데 이러한 메서드가 여럿 되다 보니 추후에 다시 메서드를 사용할 때, "어? 이거 어떨 때 true 고 false 이지?" 하는 자신을 발견할 수 있었다. 더욱이 boolean 타입은 개인의 생각에 따라 true(or false) 를 반환하는 경우가 다를 수 있기에 다른 개발자가 코드를 파악하는데 어려움을 줄 수 있다.

 

그래서 이번 'level04 계산기' 는 'boolean' 타입을 반환하는 메서드를 줄이고 각 메서드의 수행 기능을 하나로 줄이는 것에 초점을 맞추어 구현하고자 한다.

 

1. enums 패키지 위치 변경 및 Enum 클래스 수정

변경된 enums 패키지 위치

 

가장 먼저 한 것은 'enums' 패키지의 위치를 변경한 것이다. 변경한 이유는 'enums' 에 위치한 enum 클래스들은 기존의 'level03 계산기' 뿐만 아니라 'level04 계산기' 에서도 사용하고 다른 레벨의 계산기에서도 충분히 사용 가능하기에 해당 패키지는 '전역적으로 사용가능' 하다는 의도로 기존 /calculator/level03 에서 /calculator 로 위치를 변경하였다.

 

위치도 변경하였으니 'Level04 계산기' 에서 사용할 상수를 'ValidCriteria' 에 추가/수정해 주었다.

연산의 유효성을 검증할 기준 값을 가진 열거 상수 CALCULATION

 

'Level04 계산기' 에서는 입력은 한 번만 받는 방식을 사용하려 한다. 입력의 형식은 피연산자와 연산자 사이에 하나의 공백문자(' ')를 두는 방식으로 입력을 받을 것이기에 위의 이미지와 같은 정규식(CALCULATION)을 작성하게 되었다. 해당 정규식을 적용해 실수는 물론 음의 값 까지 연산에 작성할 수 있다. 그리고 'Level04 계산기' 가 추가 되었으므로 해당 계산기를 선택 할 수 있도록 계산기 번호를 추가하기 위해 아래의 부분을 추가/수정 하였다.

CALCULATOR_NUMBER 수정, LEVEL_FOUR 추가

 

이로써 'Level04 계산기' 에서 필요한 상수들은 모두 준비되었다.

 

 

2. 예외 핸들링(Exception 활용)

 이전의 계산기는 exception 을 활용하지 않아 예외를 조건문(if)을 사용해 예외를 방지해왔다. 그래서 본래의 역할과 예외 발생시 예외를 설명하는 문자열 출력 이 2가지 기능을 메서드가 가지게 되었다. 그래서 나는 본래의 역할만을 가지면서 예외는 예외대로 처리할 수 있도록 CustomException(개발자가 필요에 의해 구현한 Exception)을 활용해 예외를 처리하고자 한다.

입력 예외에 사용할 BadInputException

 

먼저 /level04/exception/BadInputException 을 생성해 최상위 예외인 'Exception' 을 상속하였다. 그리고 상속(부모) 클래스의 생성자를 호출하는 생성자를 추가하였다. 이렇게 되면 해당 클래스 객체를 생성하게 되면 객체 필드의 'message' 에 지정한 문자열을 갖는 객체가 생성된다. 자! 그럼 이런 객체는 어떻게 활용될까?

예외 객체를 활용한 /level04/validation/ValidInput.validCalculation() 메서드
ValidInput.validCalculation() 메서드 예외 처리

 

Exception 을 활용하기 위에 기존의 level03/validation 패키지의 ValidInput 클래스가 아닌 level04/validation/ValidInput 클래스를 생성하였다. 그리고 한 번에 입력된 값의 유효성을 검증할 validCalculation() 메서드를 구현하였는데, 만약 입력 된 문자열이 유효성을 통과하지 못할 경우 'BadInputException()' 객체를 생성하고 예외를 던지게 되고, 생성된 예외 객체는 메서드를 호출한 곳으로 던져지게(넘겨지게) 된다.

 

그리고 valiCalculation() 메서드를 호출한 구현부를 'try-catch' 문으로 감싸 예외가 발생하면 예외 객체에서 메시지를 꺼내 출력하도록 구현하였다. 이제 validCalculation() 메서드는 입력 값의 유효성을 검증하는 기능만을 수행하게 하고, 예외에 대한 메세지는 메세지대로 출력할 수 있게 되었다.

 

그러면 "이렇게 메서드가 수행할 기능을 하나로 줄일 필요가 있을까?" 라는 의문이 드는데 답은 "있다" 이다. 애초에 개발은 '개발하면 끝!' 이 아니다. 지속적인 유지보수가 필요한데, 하나의 메서드에 여러 기능을 구현하는 경우 자칫 이후 유지보수에서 "어? 어디다 구현했더라..." 하는 상황이 발생할 수 있고, 해당의 경우 다시 코드를 파악해야 하므로 유지보수성이 떨어지게 된다. 하지만 하나의 메서드에 하나의 기능을 구현하는 방식을 사용한다면 유지보수시 수정 부분을 빠르게 파악 가능하고 비교적 수정 범위를 좁히는 효과도 볼 수 있다. 이렇게 유지보수성이 오르는 결과를 볼 수 있기에 개인적으로 되도록 메서드에 하나의 기능을 가지도록 하는 구현에 신경을 써 보았다.

 

 

3. Level04

 이전 계산기들은 각 레벨을 이름을 갖는 클래스에 계산기의 수행 흐름을 나타내는 로직을 작성하고 끝이었다면, 이번 'Level04 계산기' 의 경우 수행 흐름 로직을 파악, 유지보수하기 쉽게 아래와 같이 작성해 보았다.

이전 계산기 보다 한 눈에 들어오는 수행 로직
Level04.start() 메서드에서만 사용되기에 다른 클래스의 접근을 막음

 

어찌보면 일부 수행부를 그냥 따로 메서드로 뺀 것으로 보일 수도 있지만 이런 방식을 사용하니 start() 메서드의 로직이 깔끔해져 파악이 쉬워 보였고, 메서드 이름을 통해 해당 수행부의 로직이 어떤 역할을 하는지 파악이 가능했다. 또 유지보수 시 수정할 기능을 가진 메서드만을 수정하면 되니 유지보수성도 이전 보다 나을거라 생각된다.

 

 

4. 마무리

 모든 건 유지보수를 위해...