드디어 대망의 프리코스의 마지막 과제! 지하철 노선도 과제이다. 역시 마지막 과제는 요구조건이 굉장히 많았다. 요구조건의 대부분은 클린코드를 향해!! 기능 요구사항은 다음과 같다.
(깃 주소 : https://github.com/qhals321/java-subway-map-precourse/blob/bomin/README.md)
기능 요구사항을 보면 엄청 자세히 나와있다. 예를 들어 역 관련 기능, 노선 관련 기능 이런 식으로 각 도메인 별 요구사항이 자세히 나와있다. 그러다보니 도메인을 나누는 데에 많은 도움이 되었고 나중에 다른 프로젝트를 개발할 때 이런식으로 도메인 별 요구사항을 잘 정리하면 코드를 작성하는 데에 있어 많은 도움이 될 것 같다.
기능부터 개발을 시작했다. 클린한 코드를 위해서는 리팩토링이 필수이니 기능 확인 작업을 위한 튼튼한 테스트 코드도 필수였다. (최대한 모든 상황의 수를 테스트 코드로 짜려다 보니 거의 시간의 80%는 테스트 코드를 작성하는 데에 사용이 되었다. 총 31가지 상황의 테스트를 짜게 되었다.)
구조는 다음과 같다.

무언가 기능 구현할 것도 많고 뷰도 많은 내용들이 있다보니 자연스레 MVC 패턴과 같이 코드가 구현되었다. 그리고 복잡한 서비스 로직이 없어서 서비스 레이어는 없이 repository - controller 흐름으로 완성하게 되었다. 이번 과제에서 기능구현은 최대한 유연한 코드가 될 수 있고 안전한 코드가 될 수 있도록 노력했다.
외부 데이터베이스를 사용한다면 어떻게 바로 연결할 수 있을까?
= Repository를 Interface로 선언해 구현 클래스만 만든다면 바로 연결이 가능하게끔 만들었다.
뷰를 어떻게 완벽히 분리할까?
= 뷰는 컨트롤러를 통해서만 접근이 가능하게끔 만들었고 도메인의 불변성을 위해 외부(View)에 내보낼 때는 DTO로 다시 매핑해서 내보내어 도메인의 불변성을 유지하려 노력했다.
Station (역)
Station 도메인을 개발할 때 가장 중요했던 건 Line 구간에 등록되어 있는 Station은 삭제가 불가하다는 전제조건이다. Station 입장에서는 Line의 모든 것을 알 필요 없이 Line 구간에 등록이 되어 있느냐만 알면 되니 int lineCount를 선언해 등록되어 있는 구간의 수를 카운트해주었다. lineCount가 0이 될 때만 삭제를 허가하면 Station의 가장 큰 이슈를 해결이 되는 것이다. (여러 구간에 등록이 가능하다, 어찌보면 N : N 관계)
Line (노선)
Line 도메인 같은 경우 구간까지 관리하게끔 구현했다. 즉, 같은 노선에 있는 역의 정보를 모두 관리하게끔 했다. 구간은 역을 삽입하고 제거하는 기능이 자주 사용이 되니 LinkedList 자료구조를 사용했다. 구간에 역을 삽입하게 되면 Station의 lineCount를 올려주는 메소드를 불러주고, 제거한다면 lineCount를 내려주는 메소드를 불러오게 되었다. 즉, Line에서 Station의 lineCount에 영향을 주는 방식으로 개발했다.
상품 구매 도메인 개발 방식과 매우 유사했다. 고객이 상품을 구매하면 재고 상품의 수는 줄여주고, 구매 취소를 한다면 재고 상품의 수는 다시 늘려준다.
도메인의 상태관리를 해준다. 이번 과제들을 통해 repository에 대한 정의가 정확히 세워진 것 같다.
과제에서 기본 뼈대가 있었는데 흥미로웠던 건 Collections.unmodifiableList(lines) 라는 메소드였다. 이런식으로 배열의 불변성을 유지할 수 있구나..!! 하지만 테스트 코드를 짤 때 저장되어 있는 모든 도메인을 삭제해야했기 때문에 새로운 배열에 옮겨 담아줬다. new ArrayList(lines)<>.
만일 자바 내부에서 데이터를 관리하는 것이 아니라 외부 데이터베이스를 사용해 관리한다면, Repository가 바뀌어야했기에 Repository는 인터페이스로 선언하고 RepositoryJava로 코드를 구현하게 되었다.