We will find a way, we always have.

-interstellar

우아한테크코스

[우테코 레벨1] 4주차 회고 (회식, 메타인지, 블랙잭, 읽기 좋은 코드)

Redddy 2024. 3. 9. 22:23

회식

월요일에 사다리 타기 미션이 끝난 기념으로 브라운과 얼굴들 회식을 했다. 🐻😁

 

시간가는줄 모르고 웃고 떠들고 했던 거 같다.

 

브라운이 한 말중 기억에 남았던 말은

너희가 왜 뽑혔는지 스스로를 못믿겠다면, 너희를 뽑은 코치를 믿어라

 

 

시간과 알코올이 더해져 약간은 각색되었을 수도 있는데, 아무튼 여전히 왜 뽑혔는지 의문이 있고, 의심이 된다면 우릴 뽑은 코치를 믿어라~ 요론 바이브의 멋진 말을 해주셨다.🤗

 

 

 

 

 

메타인지 말하기 스터디

이번주부터 메타인지 말하기 스터디를 시작하였다. 브라운이 모집을 하였는데, 브라운과 얼굴들(데일리조 이름)에서 얼굴들이 빠지면 섭하지!

나중에 들어보니 데일리조 전부가 참여한 조는 우리조밖에 없다고 하였다 :브라운꽃:

 

스터디 방식은 미션을 진행하면서 새로 배운 내용이나 공유 하고 싶은 내용을 2분 30초 동안 페어에게 내 생각을 논리적이고 간단명료하게 이야기 하는 방식이다. 그리고 이야기가 끝나면 5분 동안 질문을 받고 답변하는 식이다.

 

첫번째 메타인지 말하기 스터디의 페어는 트레였다🥛

 

나는 VO와 Record을 주제로 발표하였다. 이 개념들을 내가 이야기할 수 있음을 깨닫고, 알고 있구나라고 다시 한번 인지할 수 있었다.

 

트레의 주제는 정적 팩터리 메서드, 클래스내의 메서드 정렬 컨벤션이었는데, 오히려 이야기하는 것보다 질문하는 행위가 어려웠다. 

 

 

블랙잭 미션

벌써 세번째 미션, 블랙잭 미션이 시작되었다.

이번 미션의 페어는 제제였는데 블랙잭 미션의 난이도가 확 올라가서 그런진 몰라도 이전 페어 백호와 안나랑 페어 프로그래밍 했을 때 보다 많이 의견 충돌이 생겨 재미있었다. 

 

도메인 관련 용어 vs 누구나 아는 용어

블랙잭에서는 게임이 시작될 때 각 플레이어에게 카드를 두장 나눠주고, 힛, 스테이 여부에 따라 추가로 카드를 나눠준다. 이때 가지고 있는 카드를 저장할 일급 컬렉션을 만들고 싶었고, 이 녀석의 이름을 짓느라 열띤 토론을 하였다.

 

이번주는 계속 이 주제로 페어랑, 데일리조랑 토론한 거 같다. 다시 설명하려니 입이 아프니 PR 날릴 때 작성한 디스크립션을 복붙해야겠다.

 

읽기 좋은 코드란 무엇인가?

이번 블랙잭 미션의 테마는 클린 코드였습니다. 제가 생각하는 클린 코드는 읽기 좋은 코드라고 생각하여 읽기 좋은 코드를 만들기 위해 네이밍에 고민을 많이 하였습니다. (사실 계속 고민하여도 마땅한 이름이 떠오르지 못한 경우도 많았습니다)

네이밍을 하던 도중 “누가 읽었을 때” 읽기 좋은 코드를 짜는 것이 올바를까에 대한 질문이 들었습니다.

이번 미션으로 예를 들면 블랙잭 도메인에 관해 아무것도 모르는 사람이 읽었을 때도 쉽게 이해할 수 있는 네이밍으로 해야할지(도메인 용어를 사용하지 않는 방향), 아니면 애초에 이 코드를 읽는 사람이 해당 도메인에 대한 지식을 가지고 있을 것을 기대하고 도메인 관련된 용어를 사용해도 되는지에 대해 페어 제제와 토론을 하였습니다.

우선 저의 의견은 후자입니다. 읽기 좋은 코드를 만든다는 것은 의미를 잘 전달할 수 있는 네이밍을 하는 것인데, 도메인 용어를 사용한다면 의미를 명확하게 잘 전달할 수 있다고 생각하였습니다.

이런 고민을 가진 클래스는 Hands 입니다. 이 Hands 클래스는 참가자의 가지고 있는 카드들이 있는 일급 컬렉션입니다. 이 클래스는 2장 이상부터 많아봐야 5이하의 카드를 가지고 있어 이런 소수의 카드를 의미하는 도메인 용어로 카드 패킷을 따와 Packet 이라고 지었습니다. 페어와도 토론해보고 데일리 조들과도 이야기해보면서 패킷이라는 용어는 개발자 사이에선 네트워크 패킷과 혼동 될 수 있음을 인지하였습니다.

최종적으로는 적절한 선을 찾아서 참가자가 손에 들고 있는 카드라는 의미로 Hands로 적절하게 지었다고 생각합니다.

만약 수달이라면 어떤 식으로 이름을 지으셨을 거 같나요?

이름을 지을 때 “누구나” 읽기 쉬운 작명을 하시나요 아니면 “도메인 지식이 있는 사람이” 읽기 쉬운 작명을 하시나요?

궁금합니다!🙄

 

 

아름다운 구조

자동차 경주 미션, 사다리 타기 미션에선 다른 크루와 비교해보았을 때 구조가 크게 다르지 않았다. 하지만 이번 미션에선 페어마다 구조가 달라 서로 공유하는 재미가 있었다. 

 

블랙잭에는 모든 카드를 가지고 있는 덱이 있고, 각 참여자마다 자기가 가지고 있는 손패가 있다. 그리고 플레이어에게 딜러가 카드를 나눠준다. 그래서 우리는 처음에 딜러 객체의 필드로 덱, 플레이어, 딜러의 손패를 가지게 하였다.

 

욕심쟁이 딜러

 

 

하지만 각 플레이어에게 힛/스테이 여부를 입력받고 그에 따라 행동해야 했는데, 현재 구조에서 이 기능을 구현하려면 Dealer에도 View에 관련된 로직이 들어와야 했다.

 

뭔가 잘못됐음을 감지

 

 

이러면 딜러의 책임이 너무 커지는 거 같아 문제가 있었다. 그리고 도메인에 view를 넘겨준다는 것도 뭔가 속이 더부룩하였다.😵

 

어 뭔가 잘못된거 같은데 어디서 부터 고쳐야하지? 뭘 고쳐야하지? 애를 먹었고 머리에 과부하가 왔었다. 하지만 밥을 먹고 와서 제제가 슉슉 해보더니 꽤 깔쌈한 구조가 되었다! 역시 한국인은 밥심🍚🍚🍚🍚🍚

 

해결 방안은 딜러가 필드로 가지고 있던 플레이어를 뱉고 필요할 때 파라미터로 넘겨주는 것이었다. 덕분에 view는 컨트롤러에서만 있을 수 있었다.

 

수정한 커밋

 

메서드 정렬 컨벤션

나는 메서드를 정렬할 때 코드를 위에서 아래로 읽기 쉽게 함께 사용되는 메서드들은 붙여두는 컨벤션을 유지하고 있었다. 하지만 제제는 public 메서드를 위에 모으고 private를 아래에 모으는 컨벤션을 적용하고 있었다. (생성자,정적팩터리 메서드는 위에, getter, override 코드는 아래는 동일)

 

이유는 클래스에 들어왔을 때 이 클래스에서 사용되는 주요 메서드를 보여주고 싶은 의도였다. 듣다보니 묘하게 설득되서 public 을 위로 모으는 컨벤션으로 변경하였다.

 

긍정(?)

이번 페어 프로그래밍에선 긍정적인 마인드를 가지며 하려고 노력했던 거 같다. 테스트 성공하면 박수치고, 뭔가 해결되거나 아이디어가 떠오르면 엄치척👍을 하거나 좋아🙌를 외쳤다.

 

 

 

시간

일단 구현해야할 기능이 수두룩 빽빽하여 기능 구현하는데에 시간이 많이 소요되어 리팩터링에 신경을 많이 쓰지 못하였다. 그리고 플레이어와 딜러의 구조적인 문제도 뭔가 찜찜한 상태에서 일단 pr을 올렸었다. 올리고 나서도 리팩터링 하고 싶은 부분들이 보였지만 일단은 흐린 눈 하고 보았다😎

 

적절한 시간분배가 어렵다.

 

요구사항

이번 미션에선 특히나 애매모호한 점이 많았다. 다시 말해 기능 요구 사항이 정확하게 명시되어 있지 않았고 알아서 해석해보세요~ 하는 느낌이어서 처음에 기능 목록 작성할 때 많이 놓치고 중간 중간에 계속 추가해주었다. 아래는 주어진 요구사항, 예제, 스스로의 해석을 섞어가며 만든 기능들이다.

 

이전과 카드의 변화가 있거나 한번도 출력한 적 없으면 출력

비토 피셜 이렇게 구현한 페어는 우리말곤 못보았다고 했다.


요구사항에 명확하게 명시되어 있진 않지만 예제 코드를 보고 유추한 기능이다.

pobi는 한장의 카드를 더 받겠습니까?(예는 y, 아니오는 n)
y
pobi카드: 2하트, 8스페이드, A클로버
pobi는 한장의 카드를 더 받겠습니까?(예는 y, 아니오는 n)
n
jason는 한장의 카드를 더 받겠습니까?(예는 y, 아니오는 n)
n
jason카드: 7클로버, K스페이드

pobi가 첫번째에 y을 입력했을 때는 카드가 추가되었기에 가지고 있는 카드를 출력해주었지만, 두번째에 n을 입력했을 때는 이전 카드와 변함이 없기에 출력하지 않았다.
jason이 첫번째에 n을 입력했을 때, 아직 jason의 카드는 한번도 출력해준 적(보여준 적)이 없기에 출력을 해주었다.

 

딜러의 카드가 17이상이 될때까지 계속 카드를 받는다.

처음 받은 딜러의 카드가 16이하일 때 카드를 한번만 받으면 되는지 아니면 17 이상이 될 때까지 카드를 받는 것인지 애매하였지만 실제 블랙잭 룰을 참고하여 17이상이 될때까지 계속 카드를 받도록 구현하였다.

 
승패무


예제에선 무승부에 관한 내용은 없었지만, 카드의 합이 같고, 가지고 있는 카드의 수가 같고 21이하라면 무승부라고 판단하였다.

 

마이룰

 


참여자의 카드의 합이 21 이상이라면 더 이상 카드를 받을 수 없다.

 

참여자의 카드의 합이 21을 초과한다면 BUST 메시지를 출력하고 턴을 넘기도록 구현하였다. 마찬가지로 카드의 합이 21이라면 BLACK JACK!!! 메시지를 출력하고 더 이상 입력받지 않도록 구현하였다.

(로키가 2장의 카드로 21이여야지 블랙잭이라고 귀뜸을 주어서 다른 메시지로 수정할 필요가 있어보인다)


이렇게 21이상인 경우 턴을 넘기는 것도 실제 블랙잭 룰을 참고하여 구현을 하였는데, 예제를 보면 포비의 카드가 2하트, 8스페이드, A클로버 즉 21일 때 더 받을지 말지를 물어보고 있어 예제대로 설정된 기능은 아니다. 다시말해 예제와 다르게 동작한다.

 

이 부분에 대해 잠깐 고민해보았는데, 프리코스 때에는 “요구 사항에 명시된 출력값 형식을 지키지 않을 경우 0점으로 처리한다.“ 라고 명시되어 있지만 우테코 미션에선 딱히 형식을 지키라고 안내되어 있지 않는다. 

프리코스에서 이런 요구사항이 있었던 이유는 아마도 채점을 위한 도구라고 판단을 했고, 우테코 미션에선 페어와의 해석, 크루간의 토론이 더 중요하다고 생각하여 이런 식으로 자유롭게 두었을 거라고 생각을 했다. 

 

그래서 블랙잭 규칙, 참여자가 최선의 플레이를 할 수 있는 방식이라는 타당한 이유로 예제와는 다르게 동작하도록 설정하였다.