[우아한테크 도전기] 📝 이전 기수 최종시험 문제 풀어보기

Dev_ch·2023년 12월 14일
0

우아한테크 도전기

목록 보기
50/51
post-custom-banner

최종시험까지 얼마 안남았지만, 그래도 최대한 시험 환경에 맞추어 최종시험 문제를 풀어보고싶었다! 그래서 최종시험을 치뤘던 많은 분들이 가장 난이도가 높았다는 페어매칭관리 애플리케이션 기능을 구현하기로 하였다.

여기서 내가 임의로 설정한 환경은 아래와 같았다.

- 노트북 1대로 진행
- 제한시간은 5시간
- 시험과 동일한 요구사항을 그대로 반영하기

[Github] 이전 기수 최종시험 문제 풀이 Repository

MVC + Service 계층을 그대로 잡기!

패키지 구조는 마지막 과제였던 패키지 구조와 동일한게 잡았다. 특히 MVC + Service 계층으로 패키지 구조를 잡았으며 그 외에 util, request, response 와 같은 패키지구조로 나누어주었다.

아무래도 시간이 한정적이다보니 기능명세를 작성할때 생각보다 단순화시켰다. 너무 세세하게 들어가면 시간이 지체되고 애플리케이션 자체를 완성시키지 못할수도 있다는 생각에 기초 틀을 잡고 구조를 잡게되었다.

특히 Model은 초반에 설계했던 구조와 약간 다르게 몇가지 추가 Model이 생겼다.

InputView와 InputParser

InputView를 통해 입력받은 데이터를 Parser를 통해 파싱 후 반환을 해주었다.
여기서 반환타입은 Request 객체로 변환해주었다.

public class PairTypeRequest {
    private final Course course;
    private final Level level;
    private final String missionName;
    
    ...

프리코스를 하고있을 때 초반에는 응답, 요청 객체를 따로 생성하지 않았는데 이렇게 하다보니 넘겨야 하는 데이터가 여러가지인 경우 복잡도가 상승하여 요청과 응답 객체를 따로 생성하기로 하였다. 아무래도 프로젝트들을 하면서 얻은 것 들을 이런 곳에서 활용했던 것 같다 🚀

매칭 기능은 확실히 난이도가 있었다 🤔

단순히 페어를 매칭 시키는 것이 아닌, 페어를 매칭할 때 검증 해야할 요소들이 있었다.

- 크루들의 이름 목록을 List<String> 형태로 준비한다.
- 크루 목록의 순서를 랜덤으로 섞는다. 이 때 `camp.nextstep.edu.missionutils.Randoms`의 shuffle 메서드를 활용해야 한다.
- 랜덤으로 섞인 페어 목록에서 페어 매칭을 할 때 앞에서부터 순서대로 두명씩 페어를 맺는다.
- 홀수인 경우 마지막 남은 크루는 마지막 페어에 포함시킨다.
- 같은 레벨에서 이미 페어로 만난적이 있는 크루끼리 다시 페어로 매칭 된다면 크루 목록의 순서를 다시 랜덤으로 섞어서 매칭을 시도한다.
- 3회 시도까지 매칭이 되지 않거나 매칭을 할 수 있는 경우의 수가 없으면 에러 메시지를 출력한다.

추가적으로 파일을 읽어오는 추가적인 기능도 있었기에 확실히 복잡도가 있었다.
PairResult 라는 Model을 활용하여 생성되는 페어들을 List로 관리하게 구현하였다.
PairResult는 메인 함수에서 딱 한번 생성되어 하나의 객체로 계속 사용되게끔 구현하여 이 부분을 마치 DB에 저장, 조회, 삭제처럼 활용하였다.

가장 고민되었던 것은 Application

MVC 패턴과 Service 계층을 분리하여 설계하고 기능을 구현하였는데 Application에서 View와 Controller 사이를 조정하면서 while문과 복잡도가 상승하였다.

여기서 약간의 깨달음을 얻은 것은 아래와 같았다.

1. 예외가 발생하고 반복문이 도는 것은 최대한 Service나 View 단위에서 처리하도록 하기
2. Application 클래스는 최대한 복잡도를 줄일 것

기능을 구현하고 연결하는 과정에서 Application 클래스의 책임이 늘어나버렸다.
예외 메세지를 발생시키거나, 새로운 입력을 받아야 할때는 최대한 Service나 View 단위의 계층에서 예외나 반복문이 잘 처리되도록 구현해야할 것 같다.

TDD, 제한시간 내에서 유리할까?

TDD 는 기능에 대한 안전성을 확보해주는 중요한 기능 구현 방법이다. 하지만 최종시험은 5시간 이내 결과물을 제출하는 것 이다 보니 문제의 난이도에 따라 TDD로 기능을 구현해야 될지 고민해봐야 할 것 같다.

해당 최종시험 문제가 난이도가 있다는 말과 매칭 기능을 생각해보았을때 TDD로 구현하지 않았다. 만약, TDD로 기능을 구현하지 않았다면 해당 문제의 애플리케이션 테스트가 통과하였을때 도메인 단위의 테스트를 작성하면서 안전성을 확보해나아가야 할 것 같다.

추가적으로 문제를 얼마나 빨리 구현할지 모르겠지만, 기능 구현 자체를 최대한 빠른 시간안에 구현하고 리팩터링을 하는것이 중요할 것 같다. 그 과정속에서 테스트도 자연스럽게 작성될 것 같다.

기능이 완성된 상태에서 테스트 없이 리팩터링 하는 것은 사실 좋지 않은 방법이지만, 최대한 노력해봐야 할 것 같다. 애매하다 싶으면 테스트를 작성후에 리팩터링 하는 것이 좋을 것 같다. 사실 최종시험의 문제가 어떻게 나올지는 모르겠지만 목표로는 3시간 안에 구현, 2시간 동안 리팩터링을 생각하고 있다.

그렇기 위해선 이해능력과 설계, 기능 구현의 능력을 더욱 길러야 할 것 같다. 최종시험까지 얼마 안남았지만 최선을 다하고 내가 원하는 결과를 꼭 얻어내도록 하자 👊

profile
내가 몰입하는 과정을 담은 곳
post-custom-banner

0개의 댓글