본문 바로가기

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

로또 게임 2

코로나 바이러스 인해 2월 25일부터 재택 교육을 하게되었다.
계획은 2주지만 더 연장이 될지도 모른다고 하셨다.

우테코 생활을 한지 몇 주 지나지 않아 이런 일이 생겨서 타오르던 열정에 물을 붓는 느낌이었다.

그래도 2평짜리 고시원 생활을 잠시 접고, 집에서 편하게 잘 수 있다는 생각에 조금은 좋아하기도 했다.

재택 교육을 한다고해서 진행 중이던 미션은 멈추지 않았다. 이번 주는 저번 주에 했던 로또에서 요구사항이 조금 변한 로또 2단계 미션을 진행하였다.


이미 있는 코드를 깔끔하고 유지보수하게 좋게 리팩토링하는 것이 더 힘들다.
업무의 대부분이고 그 일을 잘해야 잘하는 개발자이다.
같은 미션을 반복적으로 설계해야 실력이 늘 수 있다.

캡틴의 강의 내용 중 일부분이다. 말씀대로 이미 있는 코드를 리팩토링하기란 상당히 까다로웠다.

요구 사항에 맞는 설계를 하기 위해서 프로그램을 처음부터 다시 짜고 싶다는 생각도 많이 들었었고 내가 짠 코드가 너무 마음에 안들었다.

주어진 시간에 맞춰서 미션을 마무리하기에 다 뒤집는 건 무리라고 생각하고 천천히 고민하며 리팩토링을 하기로 했다.

4주차에는 미션을 진행하면서

  • 처음으로 미션에서 인터페이스를 활용해볼 수 있었다.
  • 가독성이 좋은 코드, 객체지향적인 코드에 대해 더 고민해볼 수 있었다.
  • CQS 원칙
  • Iterator에 대한 오해

등에 대해 알 수 있었다.

CQS 원칙도 블로그에 정리해야 할 주제에 올라갔다.

이번 주에는 이미 있던 코드를 리팩토링하는 작업이라 새로운 이론? 지식?에 대한 학습은 적었지만 리팩토링하면서 많은 고민을 했고 클린 코드, 객체 지향적인 코드를 잘 작성하는 개발자가 되기 위해 분명 한걸음 나아갔다고 생각한다.


리뷰를 통해 깨달은 내용들을 정리해보자.

public ManualLottoCount(String count, Money money) {
        Validator.validateInteger(count);
        this.money = money;
        int lottoCount = Integer.parseInt(count);
        validProperCount(lottoCount);
        this.count = lottoCount;
}

내가 작성했었던 ManualLottoCount 클래스의 생성자 이다.
딱 봐도 생성자가 굉장히 지저분한게 보인다.

코드를 작성할 당시에는 '검증이 마쳐진 파라미터 변수만이 인스턴스 변수를 초기화 할 수 있어.'라고 생각했었다.

하지만 리뷰를 보고 아직도 정답을 정하는 습관을 못버렸구나 생각했다. 검증된 파라미터가 인스턴스 변수를 초기화 하는 것도 좋지만 코드가 저렇게 더러워진다면 굳이 그럴 필요가 없다는 걸 깨달았다.

어떤 원칙을 상황에 따라 융통적으로 적용할 수 있어야 한다는 걸 깨달았다.


이 부분 또한 마찬가지이다. 반환형이 boolean인 메서드의 네이밍은 무조건 is여야 해!라고 생각했었다. is도 좋지만 의도를 정확하게 전달하는게 목적인 메소드 네임을 너무 융통성 없게 작성했던 것 같다.

네이밍을 잘하는 것도 클린 코드를 잘 작성하는 것이라는 걸 명심하고
앞으로는 더 네이밍에 신경써야 겠다.


클래스나 메소드 네이밍을 할 때 고민한 이름을 정해주고 intelliJ의 스펠링 체크 기능을 통과하지 못하고 밑에 초록색 밑줄이 그어지면 검색해보고 초록색 밑줄이 그어지지 않게 수정을 하는 습관이 있었다.

분명 Makeable이 한 단어가 맞다고 구글에는 있는데 인텔리 J에서 계속 경고를 주니까 카멜케이스인 MakeAble로 수정했었다.

왜 IntelliJ에서 경고를 줬을까요..하고 질문해보니 IDE가 만능은 아니라 가끔 올바르지 않게 경고를 줄 때도 있다고 하셨다.

IDE를 너무 믿고 의존하지 말자고 생각했다.


나중에 Junit4를 사용할 수도 있는데 Junit4에는 DisplayName이 없다고 들어서 테스트 메소드 명의 부가적인 설명을 한글로 짓곤 했었다.

다른 프로그래머 입장에서 IDE의 경고가 눈에 거슬릴 수도 있다. 가독성도 결국엔 나 자신과 팀 동료를 위해서인데 IDE의 경고가 눈에 거슬릴 수도 있다는 생각을 못했다. 한글로 할거면 @SuppressWarnings("NonAsciiCharacters")을 붙여서 IDE의 경고를 제거하거나 DisplayName을 쓰거나 둘 중 하나는 해야겠다고 생각했다.


Iterator는 내가 로 정리하면서 열심히 학습한 내용이였다.

그래서 이번 미션을 리팩토링 하면서 입력 받은 수동 로또의 개수를 반복자 역할로 Iterator를 통해 활용해보려고 했었다.

그로인해 이런 피드백을 받을 수 있었고 Iterator에 대해 오해하고 있었다는 사실을 깨달았다.

글을 수정하면서 다시 한번 Iterator에 대해 생각할 수 있었다.


!는 가독성을 떨어뜨릴 수 있다는 말씀에 == false로 수정했었다. 하지만 리뷰어분의 의도는 그게 아니였다.

애초에 반환형이 boolean인 그 메소드는 저기에서 밖에 쓰지 않았는데 굳이 ! 나 == false로 if 문에서 체크하게 메소드를 짜는게 아니라 그냥 if 문에서 검사하는 조건에 true를 리턴하도록 메소드를 짜면 됐었다.

저렇게 작성할 당시에는 메소드명에 not이 들어가는게 뭔가 이상하다고 생각했었는데
잘못된 생각이었다. 네이밍은 의도를 전달할 목적이란 걸 상기시켰다.


위 리뷰를 받고 이해가 되지 않는 부분이 있어서 이런 질문을 했었다.

그리고 이런 친절한 답변을 받을 수 있었다.

클래스의 상태를 변경시키는 것이 무조건 안좋은 것은 아니고 위의 경우는 다른 객체와의 결합도가 높아지기 때문에 안좋은 것이였다. 또 굳이 인스턴스 변수가 하나 더 늘어난다는 단점도 있었다.

항상 클래스는 작게, 객체간의 결합도는 낮게 설계해야 한다는 것을 깨달을 수 있었다.
최소한의 인스턴스 변수인지, 결합도를 높이는 코드가 아닌지를 항상 염두하고 코드를 작성해야겠다. 경력자분에게 1대1 피드백을 받을 수 있단게 얼마나 큰 축복인지를 다시 한번 깨닫는 시간이기도 했다.


CQS 원칙이란 것을 학습할 수 있었다.

CQS 원칙에 대한 부분은 학습한 내용을 블로그에 따로 정리할 예정이지만 결론적으로 한 메서드에서 조회와 데이터 변경 두 가지의 기능을 한 번에 하면 안된다는 것을 깨달을 수 있었다.


설계를 할 때 과연 그게 자연스러운지에 대한 기준이 참 애매했었는데 이번 리뷰를 통해 자연스러운 설계를 하는 하나의 방법을 알게되었다.

애매하다 싶으면 소리내어서 읽어봐야겠다고 생각했다.

실제로 내가 설계한 부분을 소리내어 읽어보니 참 이상했다.. ManualLottoCount는 count 변수만 가지도록 수정했다.


이번 주에는 객체지향적인 설계와 코드, 클린 코드에 대해 좀 더 많이 학습할 수 있었던 것 같다.

학교 다닐때는 객체지향에 대해 공부는 하지만 객체지향적인 코드를 짜는법에 대해 자세히 알려주진 않는다. 내 코드를 봐주는 이 또한 없다. 과제는 잘 실행돼서 제출만 하면 그만이고 프로젝트는 기능만 잘 돌아가면 그만이다.

하지만 우테코에 합류하고나서 객체지향적인 코드, 클린 코드가 왜 중요한지를 제대로 배웠고 그렇게 코딩하려 노력하고, 코드리뷰를 하는 과정 속에서 우테코에 합류하기를 정말 잘했다는 생각을 많이 한다.

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

블랙잭 2  (0) 2020.03.30
블랙잭 1  (0) 2020.03.18
로또 게임 1  (0) 2020.02.26
자동차 경주 게임  (0) 2020.02.18
문자열 계산기  (0) 2020.02.10