25. 자바를 공부하며 만들었던 토이 프로젝트
Legacy Code
AutoGamer
Gamer 클래스를 상속받아, 사용자의 카드와 본인의
카드를 기억하여 자동으로 베팅하는 역할
Dealer
턴을 제어하는 로직을 가진 클래스. 턴의 승패를 판단하고,
게이머에게 칩을 분배한다. 매 턴 마다 Dealer의 상태는
초기화된다.
Gamer
칩과 카드라는 상태를 가지며, 베팅이라는 행위를 할 수
있다. 사용자의 입력을 받아 베팅한다.
IndianPoker
게임을 실행하고 종료조건에 따라 게임의 승패를 판단하는
역할. Dealer와 Gamer 객체에 의존성을 가짐
클래스 구성
26. 실제로 코드를 보기 전까진
“나름 객체지향적으로 설계한 거 같은데?”
라고 생각했습니다.
58. 처음부터 큰 문제를 한번에 해결하려 하면
어렵게 다가오고 중간에 포기하고 싶어진다.
큰 문제
1. 큰 문제를 작은 단위로 쪼갤 수 있다.
59. 테스트 케이스를 만들다 보면 큰 문제를 해결하기 위한 작은 문제,
그리고 그 작은 문제를 해결하기 위한 더 작은 문제를 찾게 된다.
이렇게 문제를 쪼개다 보면 자신이 감당할 수 있는 범위의 문제를 알게 된다.
큰 문제
중간
중간
작은
1. 큰 문제를 작은 단위로 쪼갤 수 있다.
작은
작은 작은
60. 1. 큰 문제를 작은 단위로 쪼갤 수 있다.
일단 생각나는 문제들을 적고
해결하기 위한 테스트 케이스를
만들었다.
테스트 케이스는 개발을
시작할 포인트가 되어주었고,
시작점에서 점진적으로 필요한
기능에 대한 테스트 케이스를 만들며
문제의 단위를 쪼갤 수 있었다.
61. 2. 개발의 흐름을 쉽게 파악할 수 있다.
아무리 개발을 좋아해도 365일 24시간 같은 것만 개발할 수 없는 법
개발의 흐름
62. 2. 개발의 흐름을 쉽게 파악할 수 있다.
자릴 비울땐 실패하는 테스트 케이스를 만들어 놓아
어디까지 개발했는지 파악할 수 있었다.
Dealer가 Turn의 승패를 판단하는 테스트
63. 2. 개발의 흐름을 쉽게 파악할 수 있다.
테스트 케이스의 이름은 어떤 것이든 상관없다.
때문에 자신이 파악하기 쉽게 만드는게 좋다.
또 테스트 케이스에 작성된 요소(매개변수, 리턴값)
들이 이 메소드가 어떤 일을 하는 지 알려주는 설명서가 되어준다.
BettingState Test
64. 3. 변경에 자신 있게 대처할 수 있다.
좋은 품질의 코드에는
확장이 용의하다는 조건이 있다.
이 조건은 각 기능간 의존성을 낮추어 해결할 수 있다.
A는 B가 없으면 아무것도 못한다..
65. 3. 변경에 자신 있게 대처할 수 있다.
테스트 케이스를 만들면서 자연스럽게 의존관계에 대한 고민을 하고
테스트를 쉽게할 수 있도록 의존성을 낮추는 설계를 하게 된다.
Turn 클래스와 의존관계가 있는 클래스들
66. 3. 변경에 자신 있게 대처할 수 있다.
고민은 결국 변화하는 부분(Player)와 변화하지 않는 부분(Turn의 행위)를
분리 함으로서 해결할 수 있다.
TurnTest의 일부
72. TDD를 활용해 리팩토링한 코드
Refactored
패키지 구성
controller
적절한 행위를 할 수 있도록 입력과 출력을 분기
처리하는 컨트롤러들이 있는 패키지
domain
게임의 핵심로직을 담당하는 클래스들이 모여있는 패키지
dto
도메인 로직의 처리결과를 뷰에서 보여질 수 있도록
가공한 클래스들이 모여있는 패키지
exception
직접 정의한 예외 클래스들이 모여있는 패키지
view
입력과 출력을 담당하는 클래스들이 모여있는 패키지
vo
직접 지정한 상수형 클래스들이 모여있는 패키지
support
프로그램의 실행에 직접적인 연관은 없지만
도움을 줄 수 있는 클래스들이 모여있는 패키지
73. 리팩토링한 Player 클래스의 betting() 메소드
(정확히는 Player 인터페이스를 구현한 추상클래스 AbstractPlayer의 메소드)