TDD 실습 예제 (1)
msbaek님의 강의를 보고 작성한 글입니다. 링크
개요 & 용어 정의
개요
- 소인수 분해 알고리즘 작성
- 입력 값의 소인수 구하기
TDD
로 개발을 진행합니다.(테스트 -> 해결 -> 리팩토링 순서)소수
- 1과 자기자신외의 정수로 나누어 떨어지지않는 정수
소인수
- 어떤 정수를 소수만의 곱으로 나타낼 때 그 인수가 되는 각각의 소수
0. nothing
public void nothing으로 시작
1 | public class PrimeFactorsTest { |
- 이 테스트를 통해서 현재 프로젝트가 테스트 가능한 환경인지 확인한다.
1. canFactorIntoPrimes for 1
1.1 실패 테스트 추가
- 가장 단순한 1에 대한 소인수를 구하는 테스트를 진행한다.
- 1을 제외한
소인수
들을 구해야한다. 그래서 1의소인수
는 없다.
1.2 Test 성공시키기
1 | ... |
1.3 Refactor
1 |
|
of()
의 리턴타입은Integer
인 반면에 테스트에서는Object
이므로Arrays.asList()
를 Extract 해준다.
2. canFactorIntoPrimes for 2
2에 대한 소인수를 찾아야하는데 여기서 Variable arguments(가변인자)라는걸 사용했는데 일단 한번 코드로 보자
2.1 실패테스트 추가 및 테스트 성공시키기
1 |
|
- list()에서 가변인자 ‘…’ 를 통해 파라미터를 배열로 바꾸어준다.
- 가변인자 : ‘해당 타입의 객체가 0개부터 여러개까지 매개변수로 올 수 있다.’ 라는 뜻
- Java 1.5부터 사용가능한 가변인자는 파라미터
맨 끝에만
사용가능하다.(오버로딩 주의)
2.2 Refactor
n==2
보다n>1
이 좀 더 Generic하므로 수정한다.1
2
3
4
5
6private List<Integer> of(int n) {
List<Integer> factors = new ArrayList<Integer>();
if(n > 1)
factors.add(2);
return factors;
}
3. canFactorIntoPrimes for 3
3.1 실패 테스트 추가
1 |
|
3.2 테스트 성공시키기
1 | ... |
- 모든 테스트는 최소한의 코드로 성공시키려고한다.
3.3 Refactor
assertEquals
가 반복되는게 보기 안좋다. Extract method
시키자!
Extract Variable
1 |
|
Extract Method
1 |
|
Change Signature
Change Signature
를 통해서assertPrimeFactors
메소드의 파라미터 순서를 바꿔준다(바꾸는게 보기편하다고 한다..)1
2
3
4
5
6
public void canFactorIntoPrimes() {
assertPrimeFactors(1, list());
assertPrimeFactors(2, list(2));
assertPrimeFactors(3, list(3));
}
4. canFactorIntoPrimes for 4
- 4의 소인수는
2,2
4.1 실패 테스트 추가
1 |
|
4.2 테스트 통과시키기
1 | private List<Integer> of(int n) { |
- 간단하게
2
로 나누었을 때 나머지가0
이면2
를ArrayList
에 추가
4.3 Refactor
factors
에n
을 더하는 부분을if(n>1)
밖으로 뺀다.1
2
3
4
5
6
7
8
9
10
11
12
13
14private List<Integer> of(int n) {
List<Integer> factors = new ArrayList<Integer>();
if(n > 1) {
if(n % 2 == 0) {
factors.add(2);
n /= 2;
}
}
if(n > 1)
factors.add(n);
return factors;
}
5. canFactorIntoPrimes for 8
- 그 전 숫자들은 모두 Pass, 8에서 걸림
5.1 실패 테스트 추가
1 | public void canFactorIntoPrimes() { |
5.2 테스트 성공 시키기
1 | private List<Integer> of(int n) { |
- 간단하게
if(n % 2 == 0)
부분을while
문으로 교체해서 해결
6. canFactorIntoPrimes for 9
6.1 실패 테스트 추가
1 | public void canFactorIntoPrimes() { |
6.2 테스트 성공 시키기
1 | private List<Integer> of(int n) { |
- 간단하게
3
에 대한while
문 추가로 테스트 패스
6.3 Refactor
while문의 중복이 생기게 된다.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19private List<Integer> of(int n) {
List<Integer> factors = new ArrayList<Integer>();
int divisor = 2;
if(n > 1) {
while(n % divisor == 0) {
factors.add(divisor);
n /= divisor;
}
while(n % 3 == 0) {
factors.add(3);
n /= 3;
}
}
if(n > 1)
factors.add(n);
return factors;
}
- 첫번째
while
문의 중복되는2
에 대해서extract variable
한다.
1 | private List<Integer> of(int n) { |
while
문들을for
문으로 변경해주면서 조건들을for
문에 담는다.for
문의 조건상 마지막if(n>1)
은 의미가 없기때문에 삭제한다.