다중 통화 사용에 대한 내용을 시스템의 나머지 코드에 숨기고 싶다. ( 2달러 + 3CHF ) * 5 를 보자. Money 가 수식의 가장 작은 단위가 된다. 연산의 결과로 Expression 들이 생기는데, 그 중 하나가 sum 이다. 연산이 완료되면 환율을 이용해서 결과 expression 을 단일 통화로 축약할 수 있다. 이런식으로 테스트할 수 있다.
Apache Thrift 란 직렬화 프레임워크를 사용해 SuperWebAnalytics.com 데이터 모델을 구현한다.
3.1 어째서 직렬화 프레임워크인가
많은 개발자들이 원시 데이터를 기록하는 방법으로 JSON 등의 스키마 없는 형식을 고른다. 작업을 쉽게 착수할 수 있는 장점이 있지만, 데이터 오염이 언제든지 터질 수 있는 단점이 있다. 데이터 오염 문제는 그 문제가 어떻게 발생했는지에 대한 전후사정을 거의 손에 넣을 수 없기 때문에 디버깅이 어렵다. 예를 들어, 필수 항목이 누락되어 NPE 가 발생하면 문제의 원인이 누락된 항목이라는 것은 바로 알 수 있지만 애초에 그 데이터가 어떻게 들어왔는지에 대한 정보는 없다. 강제 가능 스키마를 만들었으면, 데이터를 기록하는 시점에 오류가 나므로 데이터가 무효화된 사정과 원인에 대한 전후 사정을 알 수 있다. 그리고, 이때 발생한 오류 덕에 프로그램은 무효 데이터를 기록하지 못하므로 마스터 데이터 집합도 오염되지 않는다. 직렬화 프레임워크를 사용하면 강제가능 스키마를 쉽게 적용 할 수 있다.
3.2 Apache Thrift
Apache Thrift 는 정적 타입의 강제가능 스키마를 정의하는데 쓰이는 도구이다. 이와 유사한 도구로, Protocol Buffers 나 Avro 등이다. Apache Thrift 의 주요 요소는 구조체 (struct) 와 공용체 (union) 타입 정의이다. 이들은 다음 필드의 조합으로 구성된다.
기본 데이터 타입 : 문자열, 정수, long 정수, double 실수
다른 타입의 집합체 (리스트, 맵, 세트)
다른 구조체와 공용체
3.2.1 노드
SuperWebAnalytics.com 의 사용자 노드에서 개인은 사용자ID 나 브라우저 키기로 식별된다. 이 둘이 동시에 함께 식별에 쓰이지는 않는다. 이런 패턴은 노드를 나타날 때 흔히 볼 수 있는데, 공용체 데이터 타입과 일치한다. 하나의 값으로 여러 가지를 나타내는 타입이다.
1 2 3 4 5 6 7 8
union PersonID { 1: string cookie; 2: i64 user_id; }
@Test voidtestMultiplication(){ Dollar five = new Dollar(5); Dollar product = five.times(2); assertEquals(10, product.amount); product = five.times(3); assertEquals(15, product.amount); }
첫 번째 assertion 을 Dollar 와 Dollar 를 비교하는 것으로 재작성할 수 있다.
1 2 3 4 5 6 7 8
@Test voidtestMultiplication(){ Dollar five = new Dollar(5); Dollar product = five.times(2); assertEquals(new Dollar(10), product); product = five.times(3); assertEquals(15, product.amount); }
두 번째 assertion 도 마찬가지다.
1 2 3 4 5 6 7 8
@Test voidtestMultiplication(){ Dollar five = new Dollar(5); Dollar product = five.times(2); assertEquals(new Dollar(10), product); product = five.times(3); assertEquals(new Dollar(15), product); }
이제 임시 변수인 product는 필요없다.
1 2 3 4 5 6
@Test voidtestMultiplication(){ Dollar five = new Dollar(5); assertEquals(new Dollar(10), five.times(2)); assertEquals(new Dollar(15), five.times(3)); }
테스트를 고치고 나니, Dollar 의 amount 인스턴스 변수를 사용하는 코드는 Dollar 자신 밖에 없다. 따라서, 변수를 private 으로 변경 가능하다.
1
privateint amount;
동치성 테스트가, 동치성에 대한 코드가 정확히 동작하는 것을 검증하는데 실패하면다면 곱하기 테스트 역시, 곱하기에 대한 코드가 정확히 동작한다는 것을 검증하는데 실파헤가 된다. 이것은 TDD 를 하면서 적극적으로 관리해야할 위험 요소이다.