창천향로
4k
2016-11-28 00:06:46
7
9197

객체지향 연습하기 - 블랙잭 게임 구현


안녕하세요!

일전에 fender님의 칼럼을 읽고 순수 Java로 카드게임을 구현해봐야겠다는 생각을 하고 진행을 하게되었습니다. 

블랙잭 게임을 조금 스펙아웃하여 콘솔로 UI를 구성하여 진행하였습니다.

게임의 완성도보다는 블랙잭 게임을 구성하기 위해 필요한 객체가 무엇무엇이 있는지 생각해보고

해당 객체들이 각자 어떤 책임을 가져야하고 메소드들은 어떤 역할과 메세지를 가져야하는지를 중점으로 하였습니다.

항상 스프링속에서만 개발을 하다가 실제로 순수 Java속에서 객체에만 집중해보니 정말 많은 어색함을 느낄수 있었습니다 ㅠ;;

좀 더 연습이 필요함을 느끼기도 했으며, 제가 틀린 것, 모르는 것들에 대해 피드백을 받고자 공유하게되었습니다.

다시 일주일이 시작되는데 다들 즐거운 시작 되시길 바랍니다

감사합니다^^

본문 보기

14
8
  • 댓글 7

  • fender
    19k
    2016-11-28 10:16:11 작성 2016-11-28 11:06:28 수정됨

    제 글이 조금이라도 동기부여가 되셨다니 무척 기쁘고 보람있게 느껴집니다. 전반적으로 고민하신 흔적을 코드 곳곳에서 확인할 수 있었고 특히 메서드나 클래스가 단일한 역할만을 담당하게 하려는 노력이 인상적이었습니다.

    반면에 구현과 API의 영역이 다소 모호한 부분이 눈에 띄는 것은 아쉬운 점이었습니다. 블로그 글을 따라 읽다 보면 인터페이스 설계와 private 메서드의 구현이 병행되고 있는데, 일단 설계에 익숙해지면 취향의 문제이겠지만 그 전까지는 의식적으로 추상적 영역에서 도메인의 주요 유형들과 상호작용이 명확해질 때까지 구현은 잊어버리는 것을 추천드리고 싶습니다.

    사실 객체지향을 하는 목적 자체가 구현까지 생각하면 너무 복잡하니까 추상화해서 스케치하듯 전체 틀을 먼저 짜놓고 나중에 상세한 부분을 채워넣기 위함이기도 합니다.

    이 부분은 아마도 프로젝트 범위의 문제일 수는 있지만, 콘솔 UI를 전제로한 코드가 도메인 영역까지 침투해있는 것은 조금 고민해볼 필요가 있습니다.

    예를들어 'Player.showCards()' 같은 메서드는 과연 가지고 있는 카드를 콘솔에 뿌리는 것이 플레이어의 역할인가 자문해볼 여지가 있습니다. 만일 이 프로젝트가 카드 게임 제작을 위한 일반적인 API로 사용될 수 있다면 그런 부분은 나중에 웹기반 게임을 구현한다던지 할 때 문제가 될 것입니다.

    'Dealer.receiveCard()'을 보면 내부적인 규칙에 따라 카드를 받는 것을 거부하더라도 호출자 입장에서는 알 수 있는 방법이 없습니다. 콘솔 메시지를 보이는 건 사용자를 위한 것이지 호출하는 프로그램을 위한 것이 아니기 때문에 이러한 부분은 좀 더 개선이 필요하다고 생각합니다.

    모델링과 관련해서는 딜러가 플레이어를 상속하는 부분은 다소 어색하게 느껴집니다. 'is-a' 관계를 따져서 블랙잭 게임을 아는 사람에게 "딜러는 카드 플레이어인가?"라고 묻는다면 관점에 따라 다를 수는 있지만 그렇지 않다는 대답이 더 많이 나올 것 같긴 합니다.

    지금 설계는 딜러가 일반적인 카드를 나누어 주는 딜러의 역할 보단 플레이어와 1:1 대결을 하는 AI 호스트의 역할에 더 가깝게 설정을 했기 때문인 듯 한데, 보다 나은 설계라면 사람이나 AI나 동일한 'Player' 인터페이스로 표현되고 동작할 수 있어야 할 것 같습니다.

    한 편, 가능하면 API는 유효하지 않은 상태가 발생하지 않는 방향으로 설계하는 것이 좋습니다. 예컨대 'Card' 클래스의 생성자에 존재하지 않는 패턴(보통 'suit'이라고 부르더군요)이나 범위를 초과하는 숫자를 넣는 경우를 막으려면 열거형(enum)으로 대체하는 것도 좋은 대안입니다. 턴 관리를 플레이어에 위임하는 부분도 비슷한 맥락에서 대안을 고민해볼 수 있을 것입니다.

    카드 덱에서 카드를 뽑는 과정을 생각하면 'List.remove()' 보다는 'Stack.pop()'을 통해 구현하는 것이 더 직관적 코드가 되었을 것 같습니다.

    사소하게는 네이밍이 다소 아쉬운 부분이 눈에 띄었습니다. 가능하면 메서드 시그네쳐는 자연스럽게 읽을 수 있는 영어 문장으로 쓰는 것이 좋은데, 예를들어 'isReceiveCard'나 'receiveCardAllPlayers' 같은 이름은 올바른 영어 문장이 아닙니다.

    전반적으로 가장 아쉬운 부분은 카드나 플레이어와 같은 정적인 모델링에 비해 실제 턴이 돌아가고 게임이 진행되는 구체적인 모양새는 API 수준에서 잘 표현되지 않는다는 점이었습니다.

    아마도 그런 부분은 앞서 말한 콘솔 기반의 구현 디테일로 Game 클래스 등의 내부에 포함되었기 때문일 것인데, 좀 더 고민해보면 그런 부분도 상당히 일반화된 API로 끌어낼 수 있다고 생각합니다.

    그 밖에 추천 드리고 싶은 것은 카드 게임의 요구 조건을 테스트 케이스로 작성하는 것 정도입니다. 콘솔로 찍어보면서 테스트하는 것보다는 예를들어 '카드 덱은 xxx 장의 카드를 중복없이 제공해야 한다' 등의 규칙을 테스트로 기술하는 것이 좀 더 보기에도 깔끔하고 UI와 무관하게 테스트할 수 있어 좋았을 것 같습니다.

    지적을 많이 늘어놓아서 마치 프로젝트 내용을 비판하는 것처럼 들릴 지 모르겠지만, 개선할 수 있는 부분에 대한 피드백을 얻기 위해 쓰신 글인 것 같아 가능하면 그런 부분을 중심으로 적었기 때문일 뿐입니다.

    창천향로님은 신입이 아니시겠지만, 아마 저 정도의 설계를 비슷하게 흉내라도 낼 수 있는 개발자가 신입으로 지원했다면 다른 거 따질 것 없이 바로 뽑았을 것 같습니다.

    객체지향을 공부하는 다른 분들에게도 많은 도움을 줄 수 있는 좋은 내용을 공유해주셔서 감사드립니다.

    저도 지금 바쁜 일만 끝나면 조금 시간을 내어 스칼라 버전으로 만들어보고 싶네요.

    10
  • 창천향로
    4k
    2016-11-28 10:33:37

    @fender 으앗!! 역시 ㅠㅠ fender님 상세한 답변 감사드립니다!!

    OKKY에 글을 올릴때마다 fender님의 답변을 내심 기대하면서 올리는데 항상 좋은 피드백을 해주셔서

    많은 도움이 되고 있습니다.

    이렇게 상세하게 답변해주시니 몸둘바를 모르겠습니다 ㅎㅎ;

    특히 "과연 가지고 있는 카드를 콘솔에 뿌리는 것이 플레이어의 역할인가 자문해볼 여지가 있습니다." 

    는 말은 크게 와닿았습니다.

    현재 정리중인 내용이 끝나는대로 피드백 주신 내용을 바로 고민하고 적용해보겠습니다

    매번 감사드립니다^^


  • rime
    117
    2016-12-01 14:08:37

    @창천향로 창천향로님 블로그 잘 보고 있습니다.

    블로그 정리 너무 잘하시고 노력도 많이 하시고 개발적으로 노력 많이 하시는분 같고 본받을께 많은 분

    같아요.


    몇개 세미나는 저랑 겹쳐서 갓는데 창천향로님 블로그 보고 상기가 되더군요 


    앞으로 블로그 더욱 열심히 보겠습니다.

  • 창천향로
    4k
    2016-12-02 13:07:04

    @rime 

    헉 ㅎㅎ;;;; 과분한 칭찬 감사드립니다 ㅠㅠ;;; 

    저도 더 열심히 블로그 작성하도록 하겠습니다^^; 

    rime님도 블로그 작성해주신것 많이 공유 부탁드리겠습니다^^

    감사합니다! 

  • fender
    19k
    2016-12-06 17:28:54 작성 2016-12-06 17:30:56 수정됨

    어제 오늘 조금 여유가 생겨서 저도 스칼라 기반으로 한 번 만들어봤는데, 하다보니 너무 복잡해져서 강좌 같은 걸 하긴 어렵겠다는 생각이 들더군요.

    만들면서 깨달았는데, 위의 제 덧글에서 딜러가 플레이어를 상속 받는 부분을 지적한 부분은 제가 블랙잭의 규칙을 몰라서 착각했던 내용이더군요. 혹시 혼란이 되셨다면 양해 부탁 드리겠습니다.

    시간을 많이 투자하기도 어렵고, 만든 내용이 모범적인 코드인가 하는 확신이 안들어서 따라하기 같은 걸 만드는 건 보류할 생각입니다만, 일단 만들었으니 조금 정리해서 공개하도록 하겠습니다.

  • shalom
    148
    2016-12-12 10:56:45

    정말 이런 글과 댓글은 읽어보는 것 만으로도 너무 큰 도움이 되는 것 같습니다.

    향로님 블로그 글과 세미나 프로리뷰어 늘 눈팅 잘하고있습니다. ㅎㅎ

  • 로그인을 하시면 댓글 을 등록할 수 있습니다.