[테스트 주도 개발] 5장_솔직히 말하자면

다음을 테스트해보자.

1
5 + 10CHF = $10 (환율이 2:1 일 경우)

우선 Dollar 객체와 비슷하지만 프랑을 표현할 수 있는 객체가 필요하다. Dollar 테스트를 복사한 후 수정해보자.

1
2
3
4
5
6
7
@Test
void testFrancMultiplication() {
Franc five = new Franc(5);
assertEquals(new Franc(10), five.times(2));
assertEquals(new Franc(15), five.times(3));
}

4장에서 테스트를 단순화해놓아서 지금하는 작업이 더 쉬워졌다. 테스트 주기에는 서로 다른 단계들이 있다는 것을 다시 정리하자.

  1. 테스트 작성
  2. 컴파일 되게하기
  3. 실패하는지 확인하기 위해 실행
  4. 실행하게 만듦
  5. 중복 제거

처음 네 단계는 빨리 진행해야한다. 또한, 다섯 번째 단계 없이는 앞의 네 단계도 제대로 되지 않는다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Franc {
private int amount;

Franc(int amount) {
this.amount = amount;
}

Franc times(int multiplier) {
return new Franc(amount * multiplier);
}

public boolean equals(Object object) {
Franc franc = (Franc) object;

return amount == franc.amount;
}
}

중복이 엄청나게 많기 때문에, 다음 테스트를 작성하기 전에 이것들을 제거해야한다. equals() 를 일반화하는 것부터 시작하자.


Read more

[테스트 주도 개발] 6장_돌아온 모두를 위한 평등

5장에서 테스트를 빨리 통과하기 위해 코드를 복사해서 붙이는 죄를 저질렀다. 이제 청소할 시간이다.
Money 클래스가 공통의 equals 코드를 갖게 하면 어떨까 ? 간단한 것부터 시작하자.

1
2
class Money {
}

테스트는 여전히 돌아간다. Dollar 가 Money 를 상속받아도 여전히 어떤 것도 깨지지 않는다.

1
2
3
public class Dollar extends Money {
...
}

이제 amount 인스턴스 변수를 Money 로 옮길 수 있다.

1
2
3
class Money {
protected int amount;
}

하위 클래스에서도 변수를 볼 수 있도록, 가시성을 private 에서 protected 로 변경했다.
이제, equals() 를 위로 올릴 수 있다. 우선, 임시 변수 선언하는 부분을 변경하자.

1
2
3
4
5
public boolean equals(Object object) {
Money dollar = (Dollar) object;

return amount == dollar.amount;
}

모든 테스트가 잘 돈다. 이제 cast 부부을 변경하자.

1
2
3
4
5
public boolean equals(Object object) {
Money dollar = (Money) object;

return amount == dollar.amount;
}
Read more

[빅데이터] 2장_빅데이터를 위한 데이터 모델

마스터 데이터 집합은 람다 아키텍처에서 반드시 오염으로부터 보호되어야하는 유일한 영역이다.

2.1 데이터의 속성

대규모 소셜 네트워크 (페이스스페이스) 를 설계한다고 하자. 각각의 정보 계층은 바로 앞 단계로부터 파생되지만 단방향성이다.
앞으로 사용하게 될 용어들을 정리한다.

  1. 정보 : 지식의 일반적인 모음
  2. 데이터 : 어떤 것으로부터 파싱되지 않은 정보
  3. 질의 : 데이터에 물어볼 수 있는 질문
  4. 뷰 : 특정 타입의 질의에 응답하는데 도움을 주기 위해 만들어 지는 것

어떤 사람의 데이터는 또 다른 사람의 뷰각 될 수 있다. 어떤 광고 회사가 페이스스페이스 사용자 프로필로부터 인구 통계학 정보를 긁어 가는 수집기를 만들었다. 톰의 출생월일은 생년월일로부터 도출될 수 있기 때문에 페이스스페이스에게는 뷰 이지만, 광고 회사 입장에서는 톰에 대한 제한된 정보를 가지는 것으로 시작하므로 데이터이다.
데이터의 핵심 속성을 살펴보자 : 원시성 / 불변성 / 영원성

2.1.1 데이터는 원시적이다

가공되지 않은 데이터일수록 더 많은 질문을 그 데이터에 대해 던질 수 있다.

Read more

[빅데이터] 1장_빅데이터를 위한 새로운 패러다임

1.1 이 책의 구성

이론을 다루는 장과 사례를 다루는 장으로 나뉜다. 이론을 다루는 장은 빅데이터 시스템을 구축하는 방법을 다루고, 사례를 다루는 장에서는 이론을 구체적인 도구에 연관시킨다.

1.2 전통적인 데이터베이스를 사용해 확장하기

간단한 웹 분석 어플리케이션을 개발한다고 하자. 고객의 웹 페이지는 페이지뷰가 발생할 때마다 애플리케이션의 웹서버에 URL 정보를 보내야한다. 웹 서버는 데이터베이스에 페이지뷰에 해당하는 row 의 값을 증가시킨다. 이제 애플리케이션에 개선되며 어떤 문제가 생기는지 살펴본다.

1.2.1 큐를 사용해 확장하기

백엔드의 데이터베이스가 부하를 견디지 못해 페이지 뷰를 증가시키는 쓰기 요청을 신속히 처리하지 못해 타임 아웃이 나고 있다고 하자.
웹 서버가 데이터베이스에 직접 접근하도록 하는 대신, 웹 서버와 데이터베이스 사이에 큐를 넣는다. 그래서, 페이지뷰 이벤트를 받을 때마다 이벤트는 큐에 추가된다. 그리고, 큐에서 한 번에 100개씩 이벤트를 꺼내 하나의 데이터베이스 갱신 요청으로 일괄 처리하는 작업자 프로세스를 추가한다.

1.2.2 데이터베이스를 샤딩하여 확장하기

이 웹 분석 애플리케이션이 계속 인기가 높아져, 데이터베이스에 과부하가 다시 걸렸다고 하자. 기존의 작업자 프로세스로는 쓰기 요청을 감당할 수 없어 갱신을 병렬 처리 하기 위해 작업자 프로세스의 수를 늘렸보았지만 도움이 되지 않았다.
그래서, 데이터베이스 서버를 여러 대 사용하고 테이블을 여러 서버에 분산시키는 수평 분할, 또는 샤딩이라고 불리는 방법을 사용한다. 즉, 각 서버는 전체 테이블의 일부를 가지는 것이다. 쓰기 부하를 여러 서버, 즉 샤드로 분산 시키게 되는 것이다.
이 애플리케이션의 인기가 높어져, 데이터베이스를 더 많은 샤드로 나누었다고 하자. 샤드 개수가 변경되어서 기존의 애플리케이션 코드에도 반영을 해야하고 이것을 깜빡하면 의도하지 않은 샤드에 기록된다.

1.2.3 내결함성 문제 발생 시작

어쨌든 샤드를 늘렸는데, 이제 데이터베이스 장비에서 디스크 장애가 발생하는 상황이 왔다. 디스크 장애가 발생한 장비가 다운된 동안엔 그 디스크에 저장된 데이터를 사용할 수 없다. 해결책으로는,

Read more

[테스트 주도 개발] 3장_모두를 위한 평등

Dollar 객체같이 객체를 값처럼 쓸 수 있는 것을 객체 Value Object Pattern 이라고 한다. 값 객체에 대한 제약사항 중 하나는 객체의 인스턴스 변수가 생성자를 통해서 일단 설정된 후에는 변하지 않는다는 것이다.
값 객체가 암시하는 것은,

  1. 모든 연산은 새 객체를 반환해야한다.
  2. 값 객체는 equals() 를 구현해야한다.
1
2
3
void testEquality(){
assertTrue(new Dollar(5).equals(new Dollar(5)));
}

빨간 막대다. 가짜로 구현하는 방법은 단순히 true 를 반환하도록 하는 것이다.

1
2
3
public boolean equals(Object object){
return true;
}

(삼각측량) 예제가 두 개 이상 있으면 코드를 일반화 할 수 있다. 다음과 같이 5!=6 을 해보자.

1
2
3
4
void testEquality(){
assertTrue(new Dollar(5).equals(new Dollar(5)));
assertFalse(new Dollar(5).equals(new Dollar(6)));
}

이제 equlity 를 일반화하자.

1
2
3
4
public boolean equals(Object object){
Dollar dollar = (Dollar) object;
return amount == dollar.amount;
}

이렇게 어떻게 리팩토링해야하는지 감이 안오면 삼각측량을 사용하자. 코드와 테스트 사이의 중복을 제거하고 일반적인 해법을 구할 방법이 보이면 그냥 그 방법대로 구현하면 된다.
자, 동일성 문제는 일시적으로 해결했다. 널 값이나 다른 객체들과 비교하는 상황은 일반적이진 않지만 당장은 필요하지 않다. 할일 목록에 적어 두기만 하자.

Read more