OOP는 실 사물을 프로그래밍의 오브젝트로 반영해서 조금더 리얼 세상과 비슷한 방식으로 프로그래밍을 하게해준다.

동물 - 포유류 - 새 이런것은 너무 따분하고 ( 쓸일이 없다) / 스타크래프트의 시져탱크,벌쳐의 구현예는 어려울수 있다. ( 게임을 모른다)

포커카드+포커핸드는 OOP를 연습하기에 좋은 오브젝트이다. 적어도 고스톱 패보다 직관적이며 단순하다.



카드분석

OOP 개발의 첫걸음부터 마지막까지 먼저 해야할것은 사물에대한 관찰이고 이해이며 공감할수 있어야하는것이다.

코딩 First가 아니다. 경험을 통해 훈련해야하는것이다.

그럼 카드에대해 아는만큼 분석해보자

  • 카드는 4가지 모양이 있다 
  • 카드는 고유 숫자와 그에 해당하는 Ace~King 각각의 고유 이름이 있다.
  • 카드 셋팅은 카드의 숫자와 모양을 있으며,  King of Diamond라는 자연스러운 카드명을 사용할수 있다
  • 한번 정해진 카드는 모양과 숫자를 바꿀수없다. ( 영웅본색모드가아닌이상 불변성을 보장을 하자 / Test를 위해 생성된 카드의 주요속성을 변경할수 있지만, 이것을 허용하게될 경우 수많은 디펙에 시달릴것이다.)

카드구현

이제 분석을 토대로 , 언어의 특성을 고려하여 OOP로 구현해보자

  • 카드는 4가지 모양이 있다 → enum이라는 열거형을 사용
  • 카드는 고유 숫자와 그에 해당하는 Ace~King 각각의 고유 이름이 있다.  → 각 랭크를 배열에 맵핑
  • 카드 셋팅은 카드의 숫자와 모양을 지정할수 있으며,  King of Diamond라는 자연스러운 카드명을 사용할수 있다 →  toString 재정의
  • 한번 정해진 카드는 모양과 숫자를 바꿀수 없다 → 접근자(public/private) 의 올바른 사용 - 이것은 추후 세터를 무분별하게 지정하지 않는 객체의 불변성으로 이어집니다.
Card 작성
package game.poker;

public class Card
{

    public enum Suit
    {
        CLUBS, DIAMONDS, HEARTS, SPADES
    };

    private final Suit suit;

    private final int rank;

    private final String[] NAMES = {"Dummy", // element 0 not used
            "Ace", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine",
            "Ten", "Jack", "Queen", "King"};

    public Card(int givenRank, Suit givenSuit)
    {
        rank = givenRank;
        suit = givenSuit;
    }

    public int getRank()
    {
        return rank;
    }

    public Suit getSuit()
    {
        return suit;
    }

    public String toString()
    {
        return NAMES[rank] + " of " + suit;
    }

    public static String toString(Card[] arr)
    {
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        for (int i = 0; i < arr.length; ++i)
        {
            if (i > 0)
            {
                // every element after first one has comma before it
                sb.append(", ");
            }
            sb.append(arr[i]);
        }
        sb.append("]");
        return sb.toString();
    }
}


카드 Test 실행

이 카드는 사용성이좋고,더많은 기능을 가질수 있는 객체로 개선될수 있으며,

이러한 활동은 새로운기능과 함께 기존가진 기능을 지속적 검증을 해야하는것을 포함한다.

그것이 OOP의 설계능력을 늘릴수 있는방법이며, JUnit은 그것을 도와준다. 



Card테스트
@Test
public void cardTest(){
    for(int i=1;i<14;i++){
        Card card1 = new Card(i, Card.Suit.DIAMONDS);
        System.out.println(card1);
        //check
        if(i==13) assertThat(card1.toString()).as("cardTest").isEqualTo("King of DIAMONDS");
    }
}





  • No labels