각종 후기/우아한테크코스

[우아한 테크코스 3기] LEVEL 1 회고 - 블랙잭 2단계 미션의 2차 피드백을 받아보다 (42일차)

제이온 (Jayon) 2021. 3. 15.

안녕하세요? 제이온입니다.

 

오늘은 블랙잭 미션이 드디어 merge가 되었습니다. 그 외에 내일부터 새로운 미션을 받기 때문에 미리 책을 읽어 두었습니다.

 

 

데일리 미팅

오늘의 데일리 미팅 진행자는 우기였고, 백종원 게임을 진행해 주셨습니다. 이 게임이 처음이라서 뭔지 잘몰랐는데 룰은 간단하였습니다. 바로, 특정 음식을 네이버에 검색해서 백종원이 만든 레시피가 존재하지 않으면 게임에서 지는 것이죠.

 

저는 세상에 음식이 얼마나 많은데 이걸 못하나 생각하였는데, 피카와 샐리가 2분 동안 여러 음식을 말했는데 백종원님의 레시피가 모두 존재하였습니다. 게임을 진행하면서 별의별 음식이 나왔는데 80%는 이미 레시피가 있었던 것이라서 굉장히 신기했습니다. 백종원 그는 도대체..

 

아쉽게도 샐리는 전에 데일리 미팅을 진행한 적이 있어서 내일은 오프라인으로 피카로 당첨되었습니다.

 

 

2차 피드백

블랙잭 미션 2차 피드백이 왔고, 동시에 미션이 merge가 되었습니다! 이번 미션을 통해서 추상 클래스를 통한 상속, 도메인을 더욱 세분화하게 나누는 방법, dto 사용 목적 등을 배울 수 있었습니다.

 

피드백은 딱 하나가 있었는데, 오늘 결국 반영하지는 못하였습니다.

 

 

 

 

바로, 게임 진행 과정을 BlackjackGame과 메시지를 주고 받으면서 진행하라는 것이었죠.

 

 

    private void gameProgress(final Participants participants) {
        final Participant dealer = participants.getDealer();
        final List<Participant> players = participants.getPlayers();
        for (final Participant player : players) {
            singlePlayerGameProgress(player);
        }
        dealerGameProgress(dealer);
    }

    private void singlePlayerGameProgress(final Participant player) {
        while (!player.isBust() && InputView.askMoreCard(player.getName())) {
            player.receiveCard(CardDeck.distribute());
            OutputView.showParticipantCard(player, player.getPlayerCards());
        }
        if (player.isBust()) {
            OutputView.bustMessage();
            return;
        }
        OutputView.showParticipantCard(player, player.getPlayerCards());
    }

    private void dealerGameProgress(final Participant dealer) {
        while (dealer.checkMoreCardAvailable()) {
            OutputView.dealerMoreCard();
            dealer.receiveCard(CardDeck.distribute());
        }
    }

 

 

저는 participants를 인자로 받아와서 getter를 통해 딜러와 플레이어를 가져왔습니다. 그리고 각각 딜러와 플레이어가 메시지를 주고받으면서 게임이 진행되는 방식입니다.

 

위 방식 대신에 인자를 BlackjackGame을 받아와서 이 객체의 메소드를 이용해야 합니다. 먼저, 쉬워보이는 dealerGameProgress() 메소드부터 리팩토링하였습니다.

 

 

    private void dealerGameProgress(final BlackjackGame blackjackGame) {
        while (blackjackGame.checkDealerMoreCardAvailable()) {
            OutputView.dealerMoreCard();
            blackjackGame.receiveCardDealer();
        }
    }

 

 

BlackjackGame 안에서 딜러가 더 카드를 뽑을 수 있는지 확인하고, 가능하다면 BlackjackGame 안에서 딜러가 카드를 받는 방식으로 수정하였습니다. 맘같아서는 위 과정 자체를 BlackjackGame 자체로 옮기고 싶었지만, 출력 구문때문에 컨트롤러에 두었습니다.

 

 

문제는 딜러가 아닌 플레이어의 게임 진행 과정입니다. 

 

 

    private void singlePlayerGameProgress(final Participant player) {
        while (!player.isBust() && InputView.askMoreCard(player.getName())) {
            player.receiveCard(CardDeck.distribute());
            OutputView.showParticipantCard(player, player.getPlayerCards());
        }
        if (player.isBust()) {
            OutputView.bustMessage();
            return;
        }
        OutputView.showParticipantCard(player, player.getPlayerCards());
    }

 

 

각 조건에 따라 출력 구문이 다르고, 심지어 입력 기능도 받아야하기 때문에 위 메소드를 도무지 어떻게 BlackjackGame과 메시지를 받을지 알 수 가 없었습니다. 그래서 이 부분은 게이츠께 마지막으로 질문하였고, 답변이 오는대로 수정할 계획입니다.

 

 

그리고 게이츠께 BlackjackGame이 왜 필요한지도 질문하였는데, 이것은 다음과 같이 답변해 주셨습니다.

 

 

 

 

사용자 입장에서 블랙잭 게임 관련 객체는 알 필요가 없고, BlackjackGame 자체와 소통하는 것이 관리하기 편하다는 것이었습니다. 이것이 크루들이 이야기하는 서비스 레이어?인지는 잘 모르겠으나, 앞으로도 단순히 컨트롤러에는 독립적인 도메인과 뷰를 이용하기보다는 컨트롤러의 책임을 분산시킨 도메인 객체를 활용하도록 노력해야겠습니다.

 

 

제리와의 디자인 패턴 토론

오늘 오전에 제리와 상태 패턴과 전략 패턴의 차이, 그리고 템플릿 메소드 패턴과 전략 패턴의 사용 시기에 대해 이야기를 하였습니다. 서로 아는 부분을 이야기하면서 잘못된 부분을 지적해 주고, 몰랐던 부분은 설명해 주면서 이해하는 것이 목적이었죠.

 

저는 상태 패턴과 전략 패턴의 차이를 포스팅한 적이 있습니다. 자세한 내용은 이곳을 참고하시고, 저는 두 패턴의 차이를 '외부와의 개입'정도로 요약하였습니다. 외부에서 특정 전략을 정해주면 전략 패턴, 그렇지 않고 Context 클래스나 상태 구현 클래스 내에서 객체의 상태가 변한다면 상태 패턴인 것이죠.

 

제리도 저와 비슷한 견해였고, 본인이 잘못 생각하였던 부분을 위주로 저에게 설명해 주었습니다. 제리와 저 모두 처음에는 "전략 패턴은 한 번 전략이 생기면 프로그램이 종료될 때까지 거의 바뀌지 않는다."라고 생각하였습니다. 하지만, 프로그램 도중에도 전략은 얼마든지 바뀔 수 있고, 그것은 외부에서 setter통해 실행할 수 있다는 것을 알게 되었습니다. 그 외에 서로 오해하였던 부분을 이야기하면서 전략 패턴과 상태 패턴의 차이를 이해할 수 있었습니다.

 

 

다음으로, 템플릿 메소드 패턴과 전략 패턴의 사용 시기입니다. 저는 처음에 두 패턴은 완전히 독립적이라고 생각하여 차이점이랄게 있나 생각을 하였습니다. 하지만, 제리가 하나의 예제를 가지고 템플릿 메소드 패턴과 전략 패턴 두 가지로 구현하는 것을 보고 생각이 바뀌었습니다. 이 부분은 내용이 길어서 제리의 블로그 주소를 남기겠습니다.

 

 

그 외에 전략 패턴을 enum으로도 구현할 수 있다는 것을 알게 되어, 예제를 같이 보았습니다. 전략 하나 하나를 인터페이스로 구현하지 않고 enum에 모든 전략을 넣은 형태였습니다. 구글링을 해 보니, OCP를 약간 위반한다고 하는데 정확히 이유를 모르겠어서 내일 크루들에게 물어보려고 합니다.

 

 

마지막으로, 알고 있거나 헷갈렸던 내용을 크루와 이야기를 해 보니까 복습이 잘 되고 내용 이해가 훨씬 잘 되었습니다. 앞으로도 서로 토론하고 싶은 내용은 자주 만나거나 ZOOM으로 대화해야겠다는 생각이 들었습니다.

 

 

정리

사실 아직 시간이 오후 6시도 안 되었는데 벌써 글을 쓴 이유는 저녁에 데일리 미팅 크루들과 랜선 회식이 있고, 그 이후에는 고시원에 가야하기 때문입니다. 워니가 배민 쿠폰 15,000원을 주셨고, 이것으로 초밥을 시켜먹을 생각입니다 ㅎㅎ

 

완성된 블랙잭 미션 코드는 이곳에서 확인하실 수 있습니다.

댓글

추천 글