본문 바로가기

우아한테크코스/코드 리뷰

체스 게임 1

8주차부터 10주차까지는 우테코에 합류하고 처음으로 멘붕이 왔던 주차이다. 8 ~ 10주차에 진행했던 체스게임 미션 때문이다.

난이도가 갑자기 어려워진 느낌에 복잡하고 생각할 것도 정말 많았다. 거기에 TDD, 클린코드 등등 익숙치 않은 원칙들을 지키며 코딩하려니 힘들었다.

구현을 하던 중간에 구조를 바꿔야겠단 생각이 들어서 코드를 다 엎고 다시했었는데, 마감 시간이 다가오자 진짜 멘붕이왔다.

포비는 미션이 끝나고 이번 미션이 멘붕을 의도한 미션이라고 말씀해주셨다. 프리코스때 부터 항상 캡틴의 의도대로 다른 사람은 몰라도 나는 정확히 흘러가는 것 같다고? 느꼈다.,

우테코에서 진행하는 근로 장학에도 합류하게 됐다! 나는 코드 리뷰 부분을 맡게되었다.

의미있는 코드 리뷰를 찾아서 다른 분들이 보기 쉽게 또, 이해하기 쉽게 예제와 함께 글을 작성하는 일이다. 내 개인적인 블로그 글과는 다르게 다른 개발자님들도 본다고 생각하니까 부담감과 정확한 정보만 써야한다는 생각에 글을 쓰기가 굉장히 힘들었다.


8주차에는 위 사진의 1 ~ 3 단계 미션을 진행하였고 9 ~ 10주차에는 웹 UI와 DB를 적용하는 미션을 진행했다.

웹 UI를 적용하면서 HTML, JS, CSS의 중요성을 다시 한번 깨달았다. 프론트 쪽의 기초가 튼튼하지 않다는 생각이 많이 들었다.

레벨 2에서는 프론트 쪽의 지식도 공부한다고 한다. 그 때 열심히 공부해서 기초를 튼튼히 가져가야 겠다.


열심히 구현한 체스 미션의 리뷰 받은 부분들을 정리하자.

상수인 START, END, MOVE, STATUS는 콘솔을 통해 메뉴를 입력받고, 입력받은 메뉴를 검증하는 기능을 사용할 때 쓰는 상수들이다.

public enum Menu {
    END("end"),
    START("start"),
    MOVE("move"),
    STATUS("status");

    private static final String WRONG_MENU_MESSAGE = "잘못된 메뉴 입력입니다.";

    private final String command;

    Menu(String command) {
        this.command = command;
    }

    public static Menu of(String command) {
        return Arrays.stream(values())
            .filter(menu -> menu.isMatchCommand(command))
            .findFirst()
            .orElseThrow(() -> new     IllegalArgumentException(WRONG_MENU_MESSAGE));
    }
    ...
}

위처럼 연관성있는 상수들을 enum으로 관리함으로써 입력받은 메뉴를 검증하는 작업도 훨씬 간결해지고 역할이 분리됨으로써 상수와 메소드의 개수가 줄어들었다. 클래스가 작아지고 코드가 깔끔해짐을 느낄 수 있는 리뷰였다. 연관성 있는 상수들은 enum으로 묶는 것을 고려해보자!


이번 미션을 통해 예외를 처리하는 부분에 지식이 부족하다는걸 깨달았다. 애매하게 RuntimeException을 catch로 잡은 걸 보면... Menu 객체에는 IllegalArgumentException과 UnsupportedOperationException밖에 발생하지 않는데 말이다.

모든 에러를 잡고 싶으면 Exception을 catch하고 Menu에서 처럼 2가지 정도의 Exception밖에 발생하지 않는다면 별도 예외를 정의해서 처리하자!

이외에도 Exception 처리와 관련된 많은 글들을 읽어보며 나름의 지식을 습득했다.

  1. catch한 Exception 무시하지 않기
  2. 잡고 다시 바로 던지는 등 있으나마나 한 catch절 사용하지 않기

예외 메세지를 전부 안넣은 것은 아니고 몇개의 메소드에만 넣지 않았다. 이유는 예외가 발생할 확률이 없다고 생각했기 때문이다.

하지만 협업하는 환경에서 다른 프로그래머가 해당 메소드를 봤을 때는 생각하지 못했다. 앞으로는 협업할 때를 생각해서 항상 예외 메세지에 상황을 담는 습관을 들여야겠다. 우테코에서 이렇게 협업하기 위한 코드를 배울 때 마다 너무 좋다. 취직하기 전에는 우테코에서만 배울 수 있기 때문이다.

물론 예외는 꼭 필요할 때만 발생시켜야 하는 것이기 때문에 다음에는 Optional을 리턴하는 방식도 고려해봐야겠다.


getter를 지양해야 하는 것은 알고있었지만 위 부분은 getter를 사용할 수 밖에 없다고 생각해서 사용했었다. 하지만 getter를 사용하지 않고 해당 객체에게 생성의 책임을 맡기는 것도 방법이란 것을 깨달았다.

getter를 사용하지 않고 해결할 수 있는 방법을 더 깊이 고민해보고 getter를 사용하기로 다짐했다.


SpringBoot로 뭔가를 만들어보는 경험은 몇 번 있지만 Controller 와 Service의 역할이 헷갈렸었다.

위 리뷰를 통해 공부하고 각각의 역할을 이해하게 되었다.

이번 미션에서는 Controller를 Request를 가공해서 필요한 형태로 Service에 전달하고 View 관련 처리를 하는 역할을 주고 Service는 DAO를 통해 관련 로직 및 게임 로직을 처리하는 역할로 사용했다.

웹에 대한 지식은 Level2의 미션들을 진행하면서 천천히 꾸준히 많이 습득할 예정이다!


JDBC를 사용할 때 컴파일 에러가 뜨길래 그냥 무심코 throws 했던 SQLException에 대해 공부하고 이해할 수 있었던 리뷰이다.

첨부해주신 글의 내용을 아주 간단하게 요약하자면 SQLException은 대부분 복구 불가능한 Exception이기 때문에 Spring에서는 SQLExcpetion을 DataAcessException으로 포장해서 던져준다.

이번 미션에서 DAO 이외에도 덕지덕지 붙여놨던 throws SQLException을 지우고
기계적인 throws 선언을 막기위해 가능한 빨리 해결할 수 있는 DAO에서 SQLException을 잡아서 RuntimeException을 상속하는 DataAcessException을 따로 만들어서 포장하고 던져주었다.


DB와 체스게임을 연동할 때 체스 보드를 그대로 String으로 parshing해서 저장했었다.
그 편이 더 간단하고 성능에 좋을거라 생각했기 때문이다. 하지만 리뷰어님의 말대로 내가 했던 방식은 뷰와 내부구조에 강결합이 생길 여지가 있었다.

상황에 따라 유지보수하기 좋은 코드가 성능이 좋은 코드보다 더 의미있는 코드라는 생각을 다시 상기시킬 수 있었다.

각각 체스말들의 position과 name을 저장하고 누구 차례인지를 저장하는 turn이라는 테이블을 따로 만들어서 디비 모델링을 조금 더 세분화했다.

리팩토링하는 데 어렵고 오래걸렸던 작업이지만 다 하고나니 너무 뿌듯했었다.


멘붕도 오고 마음에 여유가 없었던 3주이지만 복잡한 도메인을 설계하고 구현해보고 웹 UI에 적용해보기 위해 관련 지식을 공부하면서 조금 더 성장한 것 같은 기분은 확실히 들었다.

다음엔 비슷한 상황이 와도 침착하게 멘탈을 유지할 수 있을 것 같다. 역시 포비에게는 다 깊은 뜻이 있다고 느꼈다. 해야할게 많아서 막막할 땐 다른 것들은 생각하지 말고, 작은 것부터 천천히 해나가는 것이 답이라는 것을 깨닫기도 했다.

Spark Java, JS, CSS 등 잘 모르는 기술을 어떻게 시작해야 할 지, 무엇을 검색해서 공부해야할 지, 감도 잡히지 않아서 굉장히 답답하고 화도 났었다.

그 과정에서 삽질을 많이했는데, 그러면서 깨달은 점이 있다.

  1. Spark Java처럼 아예 생소한 기술은 공식 API 문서를 보면서 차근차근 어떤 기능이 있는지 파악하자.
  2. JS같은 얕게 아는 기술은 여러 예제를 보며 다양하게 적용해보는게 좋은 것 같다.

앞으로 새로운 기술을 더 공부해보고 적용해봐야 확신이 서겠지만 지금 일단은 그런 것 같다.

새로운 기술, 지식을 학습하는 나만의 효율적인 방법을 체계화하기 위해 노력할 것이다!

'우아한테크코스 > 코드 리뷰' 카테고리의 다른 글

체스 게임 3  (0) 2020.05.05
체스 게임 2  (0) 2020.04.25
블랙잭 2  (0) 2020.03.30
블랙잭 1  (0) 2020.03.18
로또 게임 2  (0) 2020.03.02