티스토리 뷰

728x90

 

미션 관련 링크

블랙잭 레포지토리

https://github.com/kimhm0728/kotlin-blackjack
블랙잭 1단계 PR

https://github.com/woowacourse/kotlin-blackjack/pull/72

블랙잭(베팅) 2단계 PR
https://github.com/woowacourse/kotlin-blackjack/pull/97

 

 

 

코드 리뷰 받은 코멘트들 

테스트를 위한 부생성자

테스트를 위해 작성된 생성자는 결국 실제 코드에서도 쓰이게 되는 경우가 대부분이다.
그래서 이는 클라이언트에게 객체의 생성 방법을 여러개 열어둔 것이라고 생각한다.

 

Lazy Evaluation

기존에는 카드를 받을 때마다 카드의 점수를 계산해서, 멤버 프로퍼티를 갱신하는 로직이었다.

그런데 리뷰어님이 멤버로 카드 점수 프로퍼티를 가질 필요도 없고, 항상 Lazy Evalutaion으로 계산하라는 말씀을 해주셨다.

이후, 다른 객체가 카드 점수를 요청할 때마다 계산하도록 수정했다.

 

Lazy Evalutaion으로 수정하면, 오히려 연산이 많아질 수 있다.

하지만 오히려 각 함수의 역할과 책임이 매우 명확해졌다.

이는 더 쉬운 유지보수를 의미하고, 성능 이슈가 생긴다면 캐싱을 추가하면 된다.

 

해당 피드백이 내 고정관념을 깨트리는데 많은 도움이 되었다. 이 내용에 대한 글을 따로 작성했다. (https://thdbs523.tistory.com/413)

 

 

컨트롤러와 비슷한 클래스

게임을 진행하는 클래스를 생성했다. 어떠한 상태를 가지지 않고, 인자로 받아온 값을 계산해 다시 넘겨주기만 한다.

이 클래스가 컨트롤러와 비슷한 역할을 한다고 생각해서 질문을 드렸다.

리뷰어님은 아래의 기준을 가지고 컨트롤러를 구분한다고 하셨다.

  1. view 에 의존성이 있는가? 있다면 Controller
  2. 테스트 코드가 작성되었는가? 작성할 수 없다면 Controller

즉, 내가 생성한 클래스는 컨트롤러는 아니다.

하지만 유틸적인 성격이 강하므로, 적절한 객체에게 책임을 할당하거나 새로운 객체를 생성하라고 하셨다.

 

 

람다와 인터페이스

리팩터링을 하면서 어떤 인자는 람다로 전달하고, 어떤 인자는 인터페이스의 구현체로 전달하게 되었다.

이를 구분하는 기준이 궁금해서 리뷰어님께 질문을 드렸다. 답변은 아래와 같다.

 

인터페이스의 최대 장점 중 하나는 로직을 담고 있지 않기에, 테스트를 할 필요가 없다는 점이다.

JVM 기반에서 람다는 결국 Functional Interface로 동작한다.
byte 코드 상으로는 근본적으로는 동일하게 동작한다고 생각하고, 스타일만 통일해주면 된다.
객체지향에 익숙한 팀에서는 인터페이스 선언을 하고, 함수형에 익숙한 팀에서는 람다를 적극적으로 활용한다.

 

 

함수형적으로 설계하기

forEach 혹은 repeat 를 통해 실행시키는 로직은 side effect를 일으키는 경우가 대부분이고,
side effect 를 일으킨다면 순수 함수가 아니다. (즉, 함수형이 아니다.)

함수형적으로 설계를 강화하고 싶다면,

forEach나 repeat으로 반복해서 mutableList를 수정하기 보다는, 처음부터 불변 List를 받아오도록 리팩터링하자.

 

as-is :

repeat(반복횟수) {
    카드받아옴(mutableList add)
}

to-be :

add(반복횟수만큼카드를받아옴)

 

 

디미터 법칙

클라이언트에서는 객체가 어떠한 멤버를 가지고 있는지 알 필요가 없다.

즉, 디미터 법칙을 적용해서 멤버를 여러번 타고내려가지 않도록 수정해야 한다.

그런데 디미터 법칙을 적용하면서 어떠한 로직 없이 멤버 프로퍼티나 함수만 반환하는 코드가 많아졌다.

 

이는 추후에 유지보수성에 있어서 매우 유용하다.

반환할 객체를 다른 객체로 변경하거나, 추가적인 연산을 포함하도록 리팩터링해야 하는 경우, 함수 내부의 로직만 변경하면 되기 때문이다.

하지만 디미터 법칙을 적용하지 않고 멤버를 바로 호출한다면, 그 멤버를 사용하는 모든 코드를 찾아내서 수정해야 한다.

 

 

시간 분배와 우선순위에 대한 조언

우테코 미션에서 제일 중요하게 시간을 써야할 부분은 "객체 설계" 다.
그리고 객체 설계를 위해서는 다음 요소에 시간을 써야한다.

  1. 객체의 "역할", "책임", 그리고 다른 객체끼리의 "협력"
  2. Model 과 View 의 분리
  3. Model 의 비즈니스 로직에 대한 테스트
  4. 가독성

 

테스트에 시간을 투자하기

모든 함수에 대해서 테스트를 작성할 필요는 없지만, 미션 요구사항을 만족하고 있는지 테스트만으로도 어느정도 알 수 있도록 테스트를 작성하자.

기존에는 @ParameterizedTest 통해 하나의 큰 테스트 함수만 구현했다.

"테스트 코드는 기능 명세서와 유사하다"라는 말이 있듯이 테스트 세분화를 통해서 다른 사람이 빠르게 코드를 이해할 수 있어야 한다.

 

 

 

리뷰어/페어 피드백

리뷰어 피드백
- 개발 해야할 게 많다면, 많은 것을 한꺼번에 다 하려하기 보다 집중할 수 있는 한가지를 정하는 것도 방법임.

소통을 할 때 정성스럽게 질문글을 작성해주어서 좋았음.
- 너무 많은 범위를 질문하면 스스로 더 고민할 게 많아지므로, 객체 설계와 테스트로 소통의 주제를 정하면 좋을 것 같음.

 

페어 피드백
- 계속해서 더 나은 방법은 없을지 고민하는 모습이나 코틀린을 다루는 부분을 보면서 많이 배웠음.
- 같이 고민해야할 부분, 다음에 해야할 부분들을 적극적으로 얘기하고 정리해주어서 원활하게 소통했음.

 

 

 

블랙잭 미션을 끝내고

이번 미션에서 얻은 것 중 가장 기억에 남는 것은, "우선순위"에 대한 중요성이다.

블랙잭 미션을 진행하면서 테코톡 준비를 같이 하게 되었다.

그래서 블랙잭 미션에 온전히 집중하지 못했고, 리뷰어에게도 이에 대한 아쉬움을 내비쳤다.

 

그런데 감사하게도, 리뷰어께서 우선순위에 대한 조언을 정말 정성스럽게 해주셨다!

리뷰어 피드백에 적었듯이, 시간이 부족하다면 가장 중요한 것부터 차근차근 해나가라는 것이었다.

하지만 나는 잘하고 싶은 욕심이 너무 커서, 코드에 조금이라도 아쉬운 부분이 있으면 참을 수가 없었다 ㅋㅋ

사소한 부분까지 계속 신경쓰느라 리뷰 요청도 늦어졌고,

비교적 덜 중요한 부분을 리뷰어에게 질문하느라 가장 중요한 "객체 설계"에 집중하지 못했다.

 

리뷰어의 조언 이후, 덜 중요한 부분에 너무 많은 시간을 쏟고 있는지 계속해서 확인했다.

만약 덜 중요한 부분에 많은 시간을 쏟고 있다면, 일단은 후순위로 미뤄두고 더 중요한 부분으로 관심사를 옮겨갔다.

우선순위에 대한 조언이 정말 큰 도움이 된 것이다!

 

또한 사소하고 기본적인 부분은 리뷰 요청 전에 확실히 챙겨야겠다는 생각도 했다.

리뷰어에게 양질의 피드백을 받기 위해서다.

하지만 잘 안 된다..

reademe를 체크하지 않는다거나, ktLint를 확인하지 못한다거나.. 등등 사소한 부분을 계속 놓친다.

리뷰어에게 이런 부분에 대해 코멘트를 받을 때마다 조금 속상하다.

객체 설계에 대한 코멘트를 받을 기회를 날린 것 같았다.

 

그래도 이제는 사소한 부분은 빠르게 구현/리팩터링 하고, 객체 설계에 가장 많은 고민을 하려 의식적으로 노력하고 있다.

코드 리뷰를 진행하면서 개발 역량 뿐만 아니라 내적인 부분, 소프트스킬 역량 등을 기를 수 있어 정말 좋다.

또한 내가 욕심이 많은 편이라는 걸 처음으로 깨달았다.

내 성향이나 좋지 않은 습관, 강박들에 대해서도 잘 알게 되는 기회인 것 같다.

 

728x90
250x250
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
글 보관함