이번 3주차 미션을 시작하기 전에 2주차 미션에 대한 피드백 받은 부분을 중심으로 자동차 경주 게임을 다시 구현해봤다.
// 내가 2차 미션에 제출했던 코드 일부
public class Car {
...
public String report() {
StringBuilder sb = new StringBuilder();
sb.append(name.report() + SEPARATOR);
sb.append(position.report());
return sb.toString();
}
...
}
피드백 받은 부분을 어떻게 적용해야 할까 고민하다 구글링을 통해 MVC 패턴과 만나게 됐다. MVC 패턴에 관해서 공부하고 다시 미션을 구현하며 이를 적용해봤다.
(참고자료: 인프런 강의자료)
이 과정에서 이상하게 메서드의 이름을 짓는데 대단히 어색함을 느꼈다. 곰곰이 생각을 해보니 그전까지는 계층을 나누지 않았고 오로지 시스템과 사용자의 관점에서 메서드 이름 지어왔기 때문에 지금처럼 시스템 내부에서 계층을 나누고 그 계층 간 메세지를 주고받을때 상호 간의 관계를 고려해야 하는 상황이 처음이었기 때문이다.
시행착오 끝에 도메인 객체에 의존성이 있는 View 클래스를 만들어 구현하게 됐다. 당시에는 생각하지 못했지만 View클래스가 도메인 객체에 의존성을 가지는 게 타당한 건지 여기에 추가로 DTO 객체를 만들어서 구현해야 할지 의문이 들었다. 이 부분은 더 공부해봐야 할 것 같다.
// 피드백 받은후 다시 구현한 코드
public class ResultView {
public static void show(Result result) {
System.out.println("경기결과");
result.getResult().forEach(cars -> {
cars.getCars().forEach(car -> System.out.println(car.getName() + " : " + convertPosition(car)));
System.out.println();
}
);
}
...
}
이번 미션은 동전 자판기 구현이였다. 저번 미션 보다 예외처리가 더 많았는데 그에 따라 메서드 선언도 늘어났고 클래스 내 코드가 길어졌다. 몇 번의 리펙토링 과정에서 어느 순간 내 코드를 읽어 내려가기 어렵게 느껴졌다. 가장 큰 이유는 여태껏 나는 메서드들의 순서를 접근제한자를 기준으로 배치해서 외부에서 사용되지 않는 private 메서드는 맨 밑에 위치시켰기 때문이다.
이에 대한 해결방법은 오라클 공식 문서에서 찾을 수 있었다.
범위나 접근성보다는 기능별로 그룹화해야 한다. 예를 들어, private 클래스 메서드는 두 개의 public 인스턴스 메서드 사이에 있을 수 있습니다. 코드를 더 쉽게 읽고 이해할 수 있도록 하는 것이 목표다.
이에 따라 앞으로는 조금 더 읽기 쉬운 코드를 작성할 수 있을것 같다.
이번 미션에서는 Coin이 열거타입으로 주어졌는데 여기에 동전 개수를 mapping 하기 위해서 미션중 처음으로 map을 사용하기로 했다. 미션 요구사항대로 가장 최소한의 동전 갯수를 반환 해야 했기 때문에 당연히 자판기에 존재하는 동전 중 가장 큰 값의 동전부터 먼저 차감 시켜야 했다. 이 과정에서 처음에는 그저 익숙한 hashMap을 사용한 탓에 별도로 존재하는 동전 중 가장 큰 값의 동전을 확인하는 로직이 추가됐다. 리펙토링하는 과정에서 이번 주 피드백 중 하나였던 java에서 제공하는 api를 적극 활용하라는게 떠올랐고 구글링을 통해 LinkedHashMap과 TreeMap을 알게됐다. 미션에서는 랜덤으로 동전을 뽑아 주입하기 때문에 입력 순서를 보장하는 LinkedHashMap 대신 key값을 비교해서 자동으로 정렬해주는 TreeMap을 사용해서 리펙토링했다. 이 과정에서 열거타입은 Comparable 인터페이스를 구현한다는 사실도 알게 됐다.
사실 이번 미션에서 TDD는 커녕 제대로 된 단위 테스트를 하지 못했다. 그 이유는 시간적인 여유도 없었고 서로 얽혀있는 계층들 사이에서 어디서부터 어떻게 테스트를 진행해야 할지 혼란스러웠기 때문이다. 아직 mvc패턴과 TDD를 제대로 이해하지 못하고 있다는 방증이라고 생각한다. 이 부분은 최종 테스트가 끝난 뒤에 공부해서 차근차근 다시 구현해볼 생각이다.
벌써 이렇게 마지막 미션까지 끝났다. 항상 드는 생각이지만 지난 3주라는 시간이 정말 빠르게 흘러갔다. 돌이켜 보면 많은 걸 경험했던 시간이었고 내가 어떤 부분을 이해하고 있다고 착각했는지, 그리고 이를 통해서 어떻게 공부해야 할지 알게 된 값진 시간이었다.