[내일배움캠프] 계산기 구현 - level.03(1)

2024. 9. 6. 22:52내일배움캠프

 'level03' 계산기는 Enum, Generics, Lambda, Stream 을 적용하는 도전 단계의 과제이다. 그 중 오늘은 Enum 클래스를 생성해 적용한 'level03' 계산기를 구현하였다. 추후 수정을 위해서 어떤 의도를 가지고 구현을 했는지 구현 과정 일부를 작성하게 되었다.

 

1. 구현 계획

 일단 크게 세 가지의 목표를 세워 구현에 들어갔다. 첫 번째는 기존의 유효성 검증에 필요한 정규식이나 특정 문자열, 시스템 메세지들은 모두 출력문에 그대로 작성하였는데 이 걸  'level03' 계산기에서는 한 곳에서 다룰수 있게 Enum 클래스들을 구현해 활용하는 것, 두 번째는 기존 'level01', 'level02' 계산기와 별도로 기능이 동작하도록 분리하여 구현할 것, 마지막은 이미 구현된 클래스 및 메서드를 재사용하는 것이다.

 

 

2. 목표 수행

level03 패키지

 

 수행 결과를 스포(?)하자면 위와 같이 패키지를 구성하게 되었다. 'level03' 패키지는 'level03' 계산기의 수행로직을 작성한 'Level03' 클래스와 계산기 수행에 필요가 고정값들을 집합인 Enum 클래스들이 위치한 'enums' 패키지, 입력 값들의 유효성을 검사하는 클래스가 위치하는 'validation' 패키지로 구성되었다.

2-1. Enum 클래스 활용

 일단 요구사항 때문에 Enum 클래스를 추가하는 것은 맞지만, 기왕 적용하는거 분명한 목적을 가지고 적용하고 싶었다. 기존 'level01, level02' 계산기를 구현한 코드를 보면 아래처럼 출력문에 직접 문자열 값을 지정해 사용하였다.

level01 계산기 코드 일부
level02 계산기 코드 일부

 

해당 구현방식은 실행에는 큰 문제는 없지만 유지보수성이 너무 떨어진다. 현재 프로젝트의 코드가 많은 것이 아님에도 당장 "어...연산오류 메시지 형식을 좀 ~ 게 바꿔주세요." 하면 적어도 클래스 2개를 확인하고 해당 부분을 찾아서 코드를 직접 한땀한땀 수정해야 한다. 만약 관리 클래스가 지금의 2배, 4배가 되면 이런 작업은 상당한 고역이 될 것이다.

 

현재 걱정은 특정 문자열을 수정해야 할 경우 하나하나 찾아가며 수정해주는 것이므로 결국, 수정 할 땐 한 곳에서 수정하고 수정 사항이 자동적으로 전파되게 하면 될 거라 생각해 Enum 클래스를 활용해 위의 문제를 해결해 보았다.

SystemMessage 클래스 일부 - 메시지 내용을 값으로 갖는 열거 상수들
ValidCriteria 클래스 - 유효성 검증 기준을 값으로 갖는 열거 상수들

 

위 이미지처럼 상수에 값을 지정해두고, Enum 클래스에 상수에서 지정된 값을 꺼낼 수 있는 메서드를 구현해 기존의 직접 문자열을 지정하던 방식은 버리고 아래의 코드처럼 상수에서 값을 가져와(꺼내) 사용하게 되었다.

Enum 클래스들을 static 으로 import
Enum 클래스의 열거 상수를 사용한 메서드

 

Enum 클래스들을 static 으로 import 하여 열거 상수 사용시 Enum 클래스 명을 지정하지 않아도 열거 상수를 사용할 수 있게 하였고, 문자열을 출력하는 메서드에 열거 상수의 값(message)을 사용하였다. 위의 이미지를 보면 앞으로는 피연산자 입력 오류 메시지(ERRO_INPUT_OPERAND)를 SystemMessage 클래스에서 수정하면 해당 메서드에도 변경 값이 전파되고 같은 상수의 값을 사용하는 모든 필드 및 메서드 또한 전파된다. 이제 한 곳에서 출력 값을 관리할 수 있게 되었다!

 

2-2. 기존 'level01, level02' 계산기들과 분리

 이전에 작성해둔 코드와 현재 작성하는 코드의 차이점을 비교하기 위해 지금까지 'level' 이 다른 계산기를 구현할 때마다 서로 분리하여 구현하였다. 이번 'level03' 계산기 또한 같은 방식으로 구현하였으며 'Main' 클래스 필드에 아래의 코드를 작성해 입력 값이 '3' 일 때 'level03' 계산기가 사용되게 하였다.

Main.java - 'level03' 계산기 수행 시작부분

 

'level02' 계산기의 경우 Level02 클래스 안에서 수행이 반복되도록 구현하였지만 'level03' 계산기는 Main 클래스 내에서 수행을 반복하도록 구현하였다. 사용자의 입력 값이 '3' 일 경우 작성 로직이 수행되며 Level03 클래스 객체를 생성하고 Level03.start() 메서드의 반환 값에 따라 반복 호출(수행) 또는 수행을 중지하게 된다.

 

2-3. 기존 코드 재사용

 이전 'level02' 계산기를 구현할 때 결정한 내용으로 현재 구현하는 계산기에 요한 기능을 수행하는 메서드가 이미 존재한다면 해당 메서드를 재사용하여 중복 코드를 방지하고, 이전 작성 코드가 다른 객체 및 클래스에서도 사용 가능한지 확인하기 위해 이런 결정을 하게 되었다.

 

'level03' 계산기는 현재, 계산기 분리를 위해 작성한 Level03 클래스와 요구사항 반영을 위해 추가한 Enum 클래스, Enum 클래스의  열거 상수를 사용할 ValidInputData 클래스추가 구현하였고, 그 외의 연산을 수행하는데 필요한 클래스는 모두 'level02' 패키지의 클래스들을 재사용하였다.

 

물론 이후에 적용할 요구사항의 Generics 를 적용하면서 별도의 Calculator 클래스를 추가할 것 같아 이 때는 'calculator/level02/calculate' 의 Operation 인터페이스와 해당 인터페이스의 구현 클래스들만을 재사용하게 될 것 같다.

 

 

3. 마무리

 Enum 클래스를 사용하게 되면서 문자열을 하나하나 수정하지 않고 한 곳에서 관리할 수 있게 되었다. 이제 "이 메시지 형식, 내용 바꿔 주세요." 라는 말은 두려워 할 필요 없다!