[테스트 주도 개발] 31장_리팩토링

시스템의 설계를 작은 단계를 통해 변화시키는 방법들을 정리한다.

차이점 일치시키기

비슷해 보이는 두 코드 조각을 합리려면?
두 코드를 단계적으로 닮아가게 수정한다. 완전히 동일해지면 둘을 합쳐라.

변화 격리하기

객체나 메서드의 일부만 바꾸려면?
일단 바꿔야할 부분을 격리해라. 격리 방법으로는,

  1. 메서드 추출
  2. 객체 추출
  3. 메서드 객체
메서드 추출하기

길고 복잡한 메서드를 읽기 쉽게 만들려면?
긴 메서드의 일부분을 별도의 메서드로 분리하고 이를 호출해라. 복잡한 코드를 이해하기 쉽고, 중복을 제거하기도 좋다.

메서드 인라인

제어 흐름이 너무 산재되어 있으면?
메서드 호출하는 부분을 호출될 메서드의 본문으로 교체해라.

Read more

[테스트 주도 개발] 30장_디자인 패턴

TDD 에서 쓰일 수 있는 디자인 패턴들을 정리한다.

커맨트 패턴

간단한 메서드 호출보다 복잡한 형태의 계산 작업에 대한 호출이 필요하다면 어떻게 할까?
계산 작업에 대한 객체를 생성해서 이를 호출하면 된다. Runnable 인터페이스가 대표적인 예이다.

값 객체

공유되어야 하지만, identity (동일성) 은 중요하지 않을 때 겍체를 어떤식으로 설계할까?
객체가 생성될 때 객체의 상태를 설정한다. 그리고, 이 상태가 절대 변할 수 없도록 해라. 이 객체에 대해 수행되는 연산은 언제나 새로운 객체를 반환하게 만들어라.
별칭 문제란, 두 객체가 제 삼의 다른 객체에 대한 참조를 공유하는데, 한 객체가 공유 객체의 상태를 변화시키면, 다른 객체가 영향을 받는 문제이다. 해결하기 위한 방법으로,

  1. 의존하는 객체애 대한 참조를 외부로 알리지 않는 방법이다. 그 대신 객체에 대한 복사본을 제공한다. 이 방법의 문제는, 수행 시간이나 메모리 공간 측면에서 비효율적이다. 또한, 공유 객체의 상태 변화를 공유할 수 없다.
  2. 옵저버 패턴. 의존하는 객체에 자기를 등록해 놓고, 객체의 상태가 변하면 통지를 받는다. 이 방법의 문제는, 제어 흐름이 어렵고 의존성을 설정하고 제거하기 위한 로직이 지저분해진다.
  3. 객체를 덜 객체답게 취급. 객체는 시간의 흐름에 따라 변할 수 있는 상태를 가진다. 그런데, 이러한 특징을 제거해버려라. 이것이 값 객체이다.

모든 값 객체는 동등성을 구현해야한다. 만약,

  1. 계약을 표현하는 객체가 두 개가 있는데, 둘이 서로 같은 객체가 아니면 이 둘은 동등한것이 아니라 다른것이다.
  2. 하지만, 5프랑 짜리 동전 두개가 있는데, 이 동전들이 동일한 (identity) 동전인지는 중요하지 않다. 5프랑은 5프랑이다. 이들은 동등해야한다.(equality)
널 객체

객체의 특별한 상황은 어떻게 표현하나?

Read more

[테스트 주도 개발] 32장_TDD 마스터하기

좋은 테스트인지는 어덯게 알 수 있나?

다음은 설계에 문제가 있음을 알려준다.

  1. 긴 setUp 코드
  2. setUp 중복
  3. 실행 시간이 오래 걸리는 테스트
  4. 깨지기 쉬운 테스트
테스트를 지워야할 때는?
  1. 테스트를 삭제하고 자신감이 줄어들 것 같으면 삭제하지마라.
  2. 두 테스트 코드가 동일한 부분을 실행해도, 서로 다른 시나리오를 말한다면 그대로 남겨둬라.
프로젝트 중반에 TDD 를 도입하려면?
  1. 우선, 변경의 범위를 제한해라. 극적으로 단순화 될 수 있지만 지금 당장 변할 필요가 없으면 그냥 그대로 둬라.
  2. 그리고나서, 테스트와 리팩토링 사이의 교착 상태를 풀어줘라. 파트너와 같이 작업을 하거나, 아주 조심스럽게 작업을 할 수 있다.

시간이 지나면, 시스템에서 늘 변화하는 부분들은 테스트 주도로 된 것 처럼 보이게 될 것이다.

TDD 와 패턴의 관계는?

단순히 시스템에서 무슨 일을 할지 생각하고, 나중에 설계가 알아서 정해지도록 해라.

Read more

[빅데이터] 6장_일괄처리 계층

데이터 시스템의 목적은, 데이터에 관한 임의의 질문에 응답하는 것이다. 데이터 집합 전체를 입력으로 받는 함수는 실행 시간이 매우 오래 걸리므로, 질의의 빠르게 응답할 수 있는 다른 전략이 필요하다.
람다 아키텍쳐에서 일괄처리 계층은, 마스터 데이터 집합으로부터 일괄처리 뷰를 사전 계산해서 질의가 빠르게 처리될 수 있도록 한다.

6.1 일괄 처리 구실로 좋은 예제

각 예제는 마스터 데이터 집합 전체를 입력 받는 함수로, 질의를 어떻게 실행하는지 보여준다. 이 예제는 질의 요청이 들어올 때 즉석으로 실행하는 대신, 사전 계산을 사용하도록 구현이 변경될 것이다.

6.1.1 시간대별 페이지뷰

지정한 시간대에서 발생한 특정 URL 에 대한 페이지뷰 수의 총계를 구하는 것.

6.1.2 성별 추로

이름 데이터 집합 레코드를 사용해서 개인의 성별 추론.

6.1.3 영향력 지수

소셜 네트워크에서 개인의 영향력 지수를 구함.

6.2 일괄 처리 계층에서 계산을 수행하기

Read more

[테스트 주도 개발] 25장_테스트 주도 개발 패턴

어떻게 테스트할 것인지에 대해 이야기하기 전에, 다음 질문들을 정리해보자.

  1. 테스트한다는 것은 무엇을 뜻하는가 ?
  2. 테스트를 언제 해야하는가 ?
  3. 테스트할 로직을 어떻게 고를 것인가 ?
  4. 테스트할 데이터를 어떻게 고를 것인가?
격리된 테스트

테스트는 전체 애플리케이션을 대상으로 하는 것 보다, 작은 스케일로 하는게 좋다.
각각의 테스트는 다른 테스트와 독립적이어야한다. 즉, 문제가 하나면 테스트도 하나만 실패해야하고 둘이면 두개만 실패해야한다.격리된 테스트가 내포하는 특징은, 테스트가 실행 순서에 독립적이게 된다는 것이다. 테스트를 격리하기 위한 작업은, 시스템이 응집도는 높고 결합도는 낮은 객체의 모음으로 구성되도록 한다.

테스트 목록

뭘 테스트 해야하나 ? 시작하기 전에 작석해야할 테스트 목록을 모두 적어둬라.
우선 구현할 필요가 있는 모든 오퍼레이션의 사용 예들을 적어라. 그 다음, 이미 존재하지 않는 오퍼레이션에 대해서는 해당 오퍼레이션의 null 버젼 (아무 일도 하지 않는 버젼) 을 리스트에 적어라. 마지막으로 깔끔한 코드를 얻기 위해 이번 작업을 끝내기 전에 반드시 해야할 리펙토링 목록을 적어라.

테스트 우선

테스트는 언제 작성하는 것이 좋은가 ? 테스트 대상이 되는 코드를 작성하기 직전에 작성해라.

assertion 우선

테스트 작성할 때 단언은 언제쯤 쓸까 ? 단언를 먼저 쓰고 시작하라.
단언을 먼저 작성하면 작업을 단순하게 만들 수 있다. 소켓을 통해 다른 시스템과 통신하려고 한다고 해보자. 통신을 마친 후 소켓은 닫혀 있고, 소켓에서 문자열 abc 를 읽어와야한다고 하자.

Read more