📜 제목으로 보기

일급컬렉션에 적용된 전략패턴의 수동 데이터

01 포장된 일급컬렉션 내부 변수(list<단일객체>)를 생성자에서 랜덤으로 생성하여 초기화하는 부분에 전략패턴 적용된 상태

public class CardDeck {

    private final Deque<PlayingCard> playingCards;

    public CardDeck(final CardGenerator cardGenerator) {
        this.playingCards = cardGenerator.generate();
    }

02 문제는 수동으로 일급컬렉션 인스턴스 변수Deque<PlayingCard> playingCards = 테스트에서 case마다 가변변수 -> Add or Push로 직접 만들어 줘야한다?!

  • 전략객체 주입 대신 전략메서드 응답값까지 넣어줘서 전략메서드를 무시하고 바로 처리되게 한다.

    • () -> [Deque<PlayingCard> playingCards 미리 만들어서]
      private final Deque<PlayingCard> playingCards;
        
      public CardDeck(final CardGenerator cardGenerator) {
          this.playingCards = //전략메서드 호출() <-- 자리에 람다 오른쪽 부분이 들어간다 
          // () -> [전략메서드 호출()자리에 들어갈 수동 응답값]
      }
    
  1. 빈 deque를 만든다.

  2. 수동으로 new PlayingCard(단일객체)를 만든다.

  3. 여러개 만들어서 빈 deque에 push한다.

     @DisplayName("딜러가 버스트인 경우, 패배 결과 객체를 반환하는지 확인한다.")
     @Test
     void burst_dealer_lose() {
         //given
         PlayingCard card = new PlayingCard(Suit.CLUBS, Denomination.KING);
         PlayingCard burst1 = new PlayingCard(Suit.HEARTS, Denomination.KING);
         PlayingCard burst2 = new PlayingCard(Suit.HEARTS, Denomination.JACK);
         PlayingCard burst3 = new PlayingCard(Suit.HEARTS, Denomination.QUEEN);
         Deque<PlayingCard> rawCardDeck = new ArrayDeque<>();
         rawCardDeck.push(card);
         rawCardDeck.push(burst1);
         rawCardDeck.push(burst2);
         rawCardDeck.push(burst3);
         cardDeck = new CardDeck(() -> rawCardDeck);
        
         cardDeck.drawTo(dealer);
         cardDeck.drawTo(dealer);
         cardDeck.drawTo(dealer);
         cardDeck.drawTo(gambler);
        
         //when
         final GameResult result = GameResult.of(dealer, gambler);
        
         //then
         assertThat(result).isEqualTo(GameResult.LOSE);
     }
    

03) 대박) 수동으로 전략패턴 적용된 일급컬렉션 수동 생성하는 부분을 메서드 추출한 뒤 -> 가변 인자 등 메서드화 해주자.

01 (input)직접 넣어주는 단일객체는 인자로 받아 -> (ouput)으로 원하는 일급이 나올 수 있게 -> 메서드 추출부터 하자.

image-20220315222939621

image-20220315223046441

02 직접 입력한 input(단일객체)들이 파라미터로 안나온다면-> 파라미터 추출을 해주자.
  • 파라미터로 추출로 해줘야, 내부에 있던 실제 단일객체들이 외부에서 사용으로 빠져있다.

    image-20220315224227197

image-20220315223120056 image-20220315223142752

image-20220315223246038

03 파라미터로 지역변수화 되었으니 변수는 이제 없애준다.

image-20220315223357856

private void createCardDeck(final PlayingCard card1,
                            final PlayingCard card2,
                            final PlayingCard card3,
                            final PlayingCard card4) {

    Deque<PlayingCard> rawCardDeck = new ArrayDeque<>();
    rawCardDeck.push(card1);
    rawCardDeck.push(card2);
    rawCardDeck.push(card3);
    rawCardDeck.push(card4);
    cardDeck = new CardDeck(() -> rawCardDeck);

    cardDeck.drawTo(dealer);
    cardDeck.drawTo(dealer);
    cardDeck.drawTo(dealer);
    cardDeck.drawTo(gambler);
}
04 여러개 들어오는 단일객체에 대해서 null방지용으로 1 + 가변인자로 받아준다.
  • 첫번째 것만 직접 add

    • 가변인자는 배열로서 for문 / .stream 등을 활용한다.

      • addAll()같은 메서드가 있으면 바로 사용하면 된다.

      • 예시

          public class CardFixtureGenerator {
                    
              public static List<Card> createCards(Card firstCard, Card... remainCard) {
                  final List<Card> cards = new ArrayList<>();
                  cards.add(firstCard);
                  cards.addAll(Arrays.stream(remainCard)
                               .collect(Collectors.toList()));
                  return cards;
              }
                    
              public static void pollCards(final CardDeck cardDeck, final int pollCount) {
                  for (int i = 0; i < pollCount; i++) {
                      cardDeck.provideCard();
                  }
              }
          }
        
      private void createCardDeck(final PlayingCard card1,
                                  final PlayingCard... cards) {
        
          Deque<PlayingCard> rawCardDeck = new ArrayDeque<>();
        
          rawCardDeck.push(card1);
          for (PlayingCard card : cards) {
              rawCardDeck.push(card);
          }
          cardDeck = new CardDeck(() -> rawCardDeck);
        
          cardDeck.drawTo(dealer);
          cardDeck.drawTo(dealer);
          cardDeck.drawTo(dealer);
          cardDeck.drawTo(gambler);
      }
    
05 전략객체 대신 전메응답값이 포함된 람다주입하여 일급컬렉션 생성return으로 응답까지
  • 생성외 부분은 다시 보낸다.

    image-20220315224111532

    image-20220315224152918

    image-20220315224342809

private CardDeck createCardDeck(final PlayingCard card1,
                                final PlayingCard... cards) {
    Deque<PlayingCard> rawCardDeck = new ArrayDeque<>();
    rawCardDeck.push(card1);
    for (PlayingCard card : cards) {
        rawCardDeck.push(card);
    }
    return new CardDeck(() -> rawCardDeck);
}
06 다른 곳에서도 쓸 수 있게 testutil > xxxxFixtureGenerator > public static method
  • 직접 잘라내서 붙여하므로 직접 고쳐줘야한다.

    • F6 move method는 (프로덕션 -> 프로덕션 or Test -> 프로덕션) 정도만 지원하는 것 같다.
  • public static 으로 만들어줘야 import후 객체생성없이 바로 갖다 쓰는 유틸이 된다.

image-20220315225518922

image-20220315225619372

image-20220315225732048

public class CardDeckFixtureGenerator {
    public static CardDeck createCardDeck(final PlayingCard card1,
                                          final PlayingCard... cards) {
        Deque<PlayingCard> rawCardDeck = new ArrayDeque<>();
        rawCardDeck.push(card1);
        for (PlayingCard card : cards) {
            rawCardDeck.push(card);
        }
        return new CardDeck(() -> rawCardDeck);
    }
}

image-20220315230033682

07 사용은 가변 변수 fixture <—를 초기화해주는 해주도록 사용한다.(겹친다면 @beforeEach에서 초기화)
cardDeck = createCardDeck(
    new PlayingCard(Suit.CLUBS, Denomination.KING),
    new PlayingCard(Suit.HEARTS, Denomination.KING),
    new PlayingCard(Suit.HEARTS, Denomination.JACK),
    new PlayingCard(Suit.HEARTS, Denomination.QUEEN)
);

image-20220315230316516