[레벨2] 웹 자동차 경주 미션 회고 (230411-230424)

오잉·2023년 4월 26일
0

우아한테크코스

목록 보기
5/7
post-thumbnail

📚 미션 소개

1단계 - 스프링 프레임워크 적용

이 미션은 자동차 경주 게임을 웹 애플리케이션으로 전환하고 DB를 연동하는 미션입니다.
레벨1때 구현한 자동차 경주 게임 코드를 가져와서 웹으로 전환하고 DB와 연동하여 기록을 저장하고 조회할 수 있도록 개발해야 합니다.

  • 자동차 경주 코드 가져오기
  • 웹 요청/응답 구현하기
  • DB 연동하기

2단계 - 추가 기능 및 리팩터링

이 미션은 자동차 경주 게임에서 추가적인 기능을 구현하고 기존 기능을 수정하는 리팩터링 미션입니다.
플레이 이력 출력 기능을 추가로 구현하고 console application과 web application의 중복 코드를 제거하도록 개선합니다.

  • 게임 플레이 이력 조회 API 구현
  • 기존 기능 수정 - 출력 방식 수정
  • 리팩터링 - 중복 코드 제거

🔍 질문했던 내용들

1. 서버 내에서 예외가 발생했을 때

일반적으로 ExceptionHandler를 통해 원하는 응답으로 바꿔준다.

  • 예상되는 예외는 4xx 응답으로
  • 예상치 못한 예외같은 경우는 5xx 응답으로

2. DB에서 select쿼리로 값을 조회했는데 값을 찾을 수 없는 경우(null인 경우) 어떤식으로 반환해야 하는가?

Dao의 조회값이 없을때를 대비하여

  • 단건 조회의 경우 응답값을 Optional로 감싸서 응답
  • 다건 조회의 경우 리스트로 응답

=> Service에서 수신하여 Optional.empty인지 빈리스트인지 확인하고 예외처리 (orElseThrow 등)

3. Dao 테스트

Dao에 대한 테스트를 진행할 때

    @Test
    void 게임_저장_테스트() {
        long gameId1 = gameDao.save(3);
        long gameId2 = gameDao.save(5);

        Integer size = jdbcTemplate.queryForObject("SELECT count(*) FROM game", Integer.class);
        assertAll(
                () -> assertThat(gameId1).isEqualTo(1),
                () -> assertThat(gameId2).isEqualTo(2),
                () -> assertThat(size).isEqualTo(2)
        );
    }

이런식으로 또다른 query를 날려서 검증하는 것 보다는

    @Test
    void 자동차_저장_테스트() {
        carDao.saveAll(cars);
        List<RacingCarDto> queriedCars = carDao.findCarsById(1);

        assertThat(queriedCars).hasSize(2);
    }

이런식으로 findById를 이용해 검증하는 것이 좋다.
(+ 그러면 대부분의 메소드 테스트가 findById에 의존하게 될 것 같은데 괜찮나? -> 괜찮다)
(+ 어플리케이션 코드에서 쿼리는 될 수 있으면 피해야 한다. 왜냐하면 코드가 리팩토링 되어도 쿼리는 변경되지 않기 때문에 지속적인 유지보수가 필요해지기 때문. 그리고 쿼리가 복잡해지면 오류 가능성도 늘어난다)

4. Service에 대한 테스트

1) Mock

  • Dao를 컬렉션을 사용하는 구현체로 Mocking 해서 하는 방법

2) 통합 테스트

  • 실제 Dao를 가지고 run을 수행하고 나서, 응답이 잘 나오는지, Dao를 조회해서 Car들이 예상한 위치값으로 잘저장되어있는지 확인하는 방법

5. Service의 역할

도메인의 흐름들을 조합해주고, 데이터 영역과 주고받으며 이에 따른 응답으로 변환해주는 역할
1) Controller에서 들어온 요청을 기반으로 도메인 행위를 순서대로 수행한다.
2) DAO에게 데이터 저장 및 조회를 요청한다.
3) Controller에게 적절한 응답을 반환해준다.


📍 리뷰

1. DB 정합성, 비정규화

2. Service의 메서드 단위

3. Bean 등록 기준

Q. RandomNumberGenerator를 Bean으로 등록해야 하는가?
A.

  • 일반적으로 Util성을 가지는 클래스는 싱글턴으로 관리되고, 여러 클래스에서 사용된다는 특징을 가지기 때문에 관리의 편의성을 위해 빈으로 설정하는 편
  • RandomNumberGenerator가 다른곳에서도 필요해지면, 그냥 주입받아서 사용하면 되고, 구현체가 바뀌는경우 빈설정만 바꿔주면 되기 때문에 편리

Q. RandomNumberGenerator는 도메인인데 Bean으로 등록해도 될까?

  • 단순 난수를 생성하는게 도메인인가?

참고) Bean만 Bean을 주입받을 수 있다

4. 내부 값 검증

객체 안의 특정 필드로만 값을 비교하고 싶을 때, extracting 메소드를 사용해 해당 필드값만 추출해서 비교가 가능하다

5. @Valid & @Validated


🛁 회고 (라기보다는 레벨2에 임하는 마음가짐..?)

  • 레벨2 첫 미션인 '웹 자동차 경주 미션'을 끝냈다.

  • 레벨2는 공부해야 하는 양이 너무 많아서 자신한테 맞는 공부방법을 찾는 것이 중요하다고 한다.

  • 그래서 첫주차에 깃짱, 이리내와 이번 레벨을 어떤식으로 보내야 할까, 어떤식으로 학습해야할까에 대해 많은 대화를 나눴다.

  • 우리가 내린 결론은 괜히 이것저것 잡다하게 건드리지 않고, 중요한 키워드에 대한 공부를 정확하게 하자이다.

  • 우리는 처음 스프링을 배우기 때문에 스프링의 동작원리, 내부 구현 등 너무 깊게 공부하고자 애쓰기 보다는 (애초에 두달안에 절대 불가능) 사용법을 정확하게 익히기로 했다. 괜히 깊은 내용들을 애매하게 건들다가는 기본 사용법마저 난잡하게 꼬인 상태로 이번 레벨을 마무리하게 될 것 같았다.

  • 우리의 목표 해야할 공부를 정확히 하자를 이루기 위해

    • 매 미션마다 우테코 강의자료에 제시된 keyword를 가장 중요한 키포인트로 잡고
    • 미션 기간(2주) 동안 해당 keyword를 정확히 공부하기로 했다.
    • 그리고 해당 keyword에 대해 공부한 내용을 블로그에 정리해 업로드하기로 했다.
    • 블로그에 문서화(?)함으로서 뭉개듯이 학습하지 않고 많은 내용을 정확히 머리에 넣을 수 있었다.
  • 또한 깃짱, 이리내, 콩하나, 에코와 '서울 단후회'를 결성했다.

    • '서울 단후회'란 도쿄 리벤저스의 도쿄만지회를 따라한 이름이다ㅋㅋㅋ
    • 여기서 '단후'란 '단순한 백엔드'라는 의미로 'minimal backend'. 즉, 우리의 목표인 해야할 공부를 정확히 하자이다.
    • 잡다하거나 심화 지식 XXX. 중요한 개념을 정확히 공부하자!!!
  • 레벨1에서 하던 '소소한 코드리뷰 스터디'도 여전히 참여 중이다.

    • 매주 금요일날 미션에 대한 pr을 올리고, 주말동안 서로에게 코드리뷰를 진행하고, 그 다음주 월요일날 회의실에 다같이 모여서 리뷰와 질문에 대해 이야기 하는 방식으로 진행된다.
    • 우리 스터디 멤버들이 다들 굉장한 실력자+스프링숙련자라서..
      뭔가 레벨1과는 다르게 스터디 중 대화?를 따라가기에 힘이 든다. 근데 나름 기 안 죽고 꾸역꾸역 하고 싶은 말과 모르는 부분에 대한 질문 다하는 중 ㅎㅎㅎ 항상 내 질문에 대답해줘서 고마워 얘들아 ><
    • 얼른 공부해서 의미있는 리뷰와 의미있는 토론을 할 수 있게 노력할게 얘들아ㅎㅎㅎ
  • 체인저의 섭외를 받아서 '레벨 인터뷰 스터디'에 참여하게 되었다.

    • 매 미션이 끝나는 주의 일요일 밤까지 각자 레벨로그를 작성하고, 다음날 월요일 저녁에 다같이 모여서 레벨 인터뷰를 하는 방식으로 진행된다.
    • 이번주 월요일(230424)에 첫 스터디를 진행했다. 이번 내 인터뷰 팀은 다즐, 민트, 땡칠 이었다.
    • 나는 사용법 위주로 공부했는데, 생각보다 심화된 질문(ex. 생성자 주입을 쓰면 순환참조를 미리 알 수 있는데, 왜 Setter주입으로는 알 수 없을까요?)들이 좀 나와서 당황했지만? 사실 크게 개의치 않았다😃 왜냐하면 내가 이번 미션에서 중요시 했던 것들에 대한 답변은 잘 했다고 생각하기 때문이다.(뭐 심화된 내용은 코치님들 말씀처럼 레벨3,4에 충분히 다룰 수 있다고 생각한다. 그렇기 때문에 지금은 꿋꿋히 내 공부를 하려고 한다)
    • 하지만 말할 때 시선처리, 너무 긴 답변, 고개 까딱거림 등 평소에도 생각했던 나의 문제점이 또다시 드러나서..ㅋㅋ 남은 스터디 동안 열심히 고쳐봐야겠다!
  • 결론만 말하자면 레벨2 첫 2주가 너무 만족스럽다! 목표(해야할 공부를 정확히 하자)를 이루기 위해, 이번 미션의 중요한 키워드들을 날짜별로 적절히 분배해서 매일매일 꾸준히 공부했다.

  • 특히 내가 공부한 내용들을 글로 다 정리해서 매우 만족스럽다! 내용이 너무 방대해서 머리에 들어오지 않았었는데, 나름 연관있는 주제를 나누고 그 주제 안에서 의미있는 목차를 정하기 위해 고민하는 과정을 거쳤더니, 나만의 공식문서가 만들어진 것 같다😋 (2주 동안 무려 13개의 게시글을 업로드했다)

  • 요즘 공부하는 것이 너무 즐겁다! 마구마구 공부해서 똑똑해져야지!!!!!! 우하하

profile
오잉이라네 오잉이라네 오잉이라네 ~

0개의 댓글