2주차에 대해 공통 피드백이 도착하였다.
공통 피드백은 아래와 같았다.
2주차의 주요한 피드백은 아래와 같다.
첫 번째로는
내가 할 수 있는 클래스를 분리하는 연습에 최대한 집중을 해보았다.
제시된 기능들을 구현 시 클래스를 분리하는 연습에 집중하여 클래스별 1 기능만 수행할 수 있도록 작성하니 가독성이 높아지고 이후 수정이 필요한 부분이 생겼을 경우 유지 보수가 편리하여 클래스 분리 연습이 왜 필요한지 이해할 수 있었다.
아래 예시를 보자.
하나의 메소드내에 여러 역할을 준 경우
public static List<Integer> jugementNumberWithBonus(int InputMoney) {
List<Integer> resultNumber = new ArrayList<>();
List<List<Integer>> correctNumberList = FinalUserNumberGenerator.FinalUserNumber(InputMoney);
List<Integer> correctNumber = Lotto.CorrectLottoNumber();
int bonusNumber = BonusNumberGenerator.createBonusNumber(correctNumber);
for(int i=0; i<InputMoney; i++) {
int returnNumber = CompareNumber.jugementNumber(correctNumberList.get(i), correctNumber);
if(returnNumber == 5) {
returnNumber = JudgmentBonusNumberGenerator.JudgmentBonusNumber(correctNumberList, bonusNumber, returnNumber, i);
resultNumber.add(returnNumber);
continue;
}
if(returnNumber == 6) {
returnNumber = 7;
}
resultNumber.add(returnNumber);
}
return resultNumber;
}
코드가 아주 지저분 한 것을 볼 수 있다.
물론 변수명으로 대략적으로 어떤 역할을 하는지 예상은 할 수 있겠지만 가독성이 많이 떨어지는 것을 볼 수 있다.
하지만 아래와 같이 메서드만 두개로 나누어주어도 변수명으로 어떤 역할을 하는지 더욱 명확하게 알 수 있다.
(물론 best practice는 아니며 리팩터링이 더 필요한 코드이다..)
public static List<Integer> jugementNumberWithBonus(int InputMoney) {
List<List<Integer>> correctNumberList = FinalUserNumberGenerator.FinalUserNumber(InputMoney);
List<Integer> correctNumber = Lotto.CorrectLottoNumber();
int bonusNumber = BonusNumberGenerator.createBonusNumber(correctNumber);
return BonusNumberCalculatorGenerator.BonusNumberCalculator(InputMoney, correctNumberList, correctNumber, bonusNumber);
}
public static List<Integer> BonusNumberCalculator(int InputMoney, List<List<Integer>> correctNumberList, List<Integer> correctNumber, int bonusNumber) {
List<Integer> resultNumber = new ArrayList<>();
for(int i=0; i<InputMoney; i++) {
int returnNumber = CompareNumber.jugementNumber(correctNumberList.get(i), correctNumber);
if(returnNumber == 5) {
returnNumber = JudgmentBonusNumberGenerator.JudgmentBonusNumber(correctNumberList, bonusNumber, returnNumber, i);
resultNumber.add(returnNumber);
continue;
}
if(returnNumber == 6) {
returnNumber = 7;
}
resultNumber.add(returnNumber);
}
return resultNumber;
}
이렇게 둘로 나눔으로써 이후 유지보수를 할때에도 역할분담을 명확히 하여 쉽게 할 수 있는 장점이 있다.
이번 3주차를 진행하며 가장 크게 신경썼던 부분은 클래스(객체)를 분리하는 연습 이었다.
가능한 작은 단위의 메소드들로 만들려고 노력하였고(=15줄 이내의 코드를 작성하시오) 그 결과 총 17개의 클래스(Application 제외)를 생성하게 되었다.
(클래스, 함수명 짓는것이 정말 어렵다는 것을 다시 한 번 깨달았다..)
두 번째로는
단위 테스트코드를 작성하는 연습이었다.
- 테스트의 중요한 목적 중 하나는 내가 작성하는 코드에 대해 빠르게 피드백을 받는 것이다.
- 시작부터 큰 단위의 테스트를 만들게 된다면 작성한 코드에 대한 피드백을 받기까지 많은 시간이 걸린다.
- 그래서 문제를 작게 나누고, 그 중 핵심 기능에 가까운 부분부터 작게 테스트를 만들어 나간다
테스트코드 작성을 통해 피드백을 받으려다보니 어려움이 많았다.
구현하기에 바쁜 나를 볼 수 있었고 그것은 좋은 구현방식이 아니었다.
뒤돌아보니 결국 다시 틀린부분으로 돌아가게 되어있었고 테스트코드를 처음부터 잘 작성하였으면 되었을 일이었다.
아래 간단한 예시를 함께 보겠다.
@Test
void InputMoney() {
assertSimpleTest(() -> {
runException("1000");
assertThat(output()).contains("1개를 구매했습니다.");
});
}
이는 처음 코드가 실행되고 1000을 입력하였을때 “1개를 구매했습니다.” 라는 출력문이 포함이 되었는지에 대한 테스트 코드이다.
이렇게 테스트코드를 만든 후 입력기능의 코드와 그에 맞는 출력기능을 구현하였다면 구현한 코드에 대한 확인을 할때 매번 눈으로 확인하지 않고 빠르게 어디서 어떤 부분이 에러가 났는지 확인할 수 있었을 것이다. 물론 눈으로 보며 디버깅을 통해서도 할 수 있지만 그것은 아주 좋은 방법만은 아니다.
그리고 테스트코드 실행시 반복적인 실패로 인해 다시 처음부터 요구사항을 아주 자세히 읽어보았다. 그리고는 메일에 도착한
‘위 요구 사항은 예외 발생 시 로그를 남기고, 프로그램이 종료되는 상황을 생각해 보세요.’
문구에서 로그를 남기고 종료된다는 말에 영감을 얻었다.
여기서 예외 처리에 대해 자세히 알아볼 수 있었다.
아래 예시를 보자
public static void main(String[] args) {
int[] intArray= {10};
try {
System.out.println(intArray[2]); // 예외발생 -> 프로그램 종료
}catch(ArrayIndexOutOfBoundsException e){
System.out.println("intArray 배열에는 2번방이 없습니다.");
}
System.out.println("프로그램을 종료합니다.");
}
여기서 try문에서 존재하지 않는 배열을 접근하려하여 ArrayIndexOutOfBoundsException 예외 가 발생되었다. 예외가 발생하였으므로 catch문에서 해당 예외를 잡아 밑에있는 System.out.println();문을 실행하는 것이다.
이 과정을 통해 어떻게 로깅을 남기고, 프로그램을 종료하는지 알 수 있었다.
3 주차 미션 제출은 2/2 로 테스트통과를 하였다.
비록 통과는 하였지만 우테코에서 요구하는 사항(리팩터링, 단위 테스트코드 작성 등)들을 모두 만족하지는 못하였던 것 같다.
이번 과정은 다른 주차에 비해 얻어가는 것이 매우 많은 한 주 였다.
최소단위의 클래스, 메소드 만들기 그리고 단위 테스트 만들어보기 자세한 README 작성 등 앞으로 개인적인 발전에 있어 길잡이가 되어주는 순간들이라고 생각된다.
이번 주차의 내용들을 잊지 않고 앞으로 있을 미션들에 대해 반드시 적용시켜보려 더욱 노력하는 내가 되어야 겠다.