험블 객체 패턴
- 험블 객체 패턴은 디자인 패턴으로, 테스트하기 어려운 행위와 테스트하기 쉬운 행위를 단위 테스트 작성자가 분리하기 쉽게 하는 방법으로 고안되었음
- 테스트하기 어려운 행위는 모두 험블객체로 옮기고, 나머지 모듈에는 테스트하기 쉬운 행위를 모두 옮김
- 예를 들어 GUI의 경우 단위 테스트가 어려움. 그러나 GUI에서 수행하는 행위의 대다수는 쉽게 테스트할 수 있음
프레젠터와 뷰
뷰
: 험블 객체이고 테스트하기 어려움. 이 객체에 포함된 코드는 가능한 한 간단하게 유지
프레젠터
: 테스트하기 쉬운 객체. 프레젠터의 역할은 애플리케이션으로부터 데이터를 받아 화면에 표현할 수 있는 포맷으로 만드는 것임- 예를 들어 애플리케이션에서 어떤 필드에 날짜를 표시하고자 한다면, 애플리케이션은 프레젠터에 Date 객체를 전달하고 프레젠터는 해당 데이터를 적절한 포맷의 문자열로 만들고, 이 문자열을 뷰 모델이라고 부르는 간단한 데이터 구조에 담음. 그러면 뷰는 뷰 모델에서 데이터를 찾는다.
- 뷰는 뷰 모델의 데이터를 화면으로 로드할 뿐이며, 이 외에 뷰가 맡은 역할은 전혀 없다. 따라서 뷰는 보잘것 없다(
humble
)
테스트와 아키텍처
테스트 용이성은 좋은 아키텍처가 지녀야 할 속성으로 오랫동안 알려져 왔음. 험블 객체 패턴이 좋은 예인데, 행위를 테스트하기 쉬운 부분과 테스트하기 어려운 부분으로 분리 함으로써 아키텍처 경계가 정의됨
예시1 : 데이터베이스 게이트웨이

- Database 는 험블객체임. 테스트하기 어렵고(외부 의존성을 가지기 때문에. DB 접근 직접해야하니까) DB에서 데이터를 가져오기만 하기에 맡은 역할이 크지 않다.
- Usecase Interactor는 애플리케이션에 특화된 업무 규칙을 캡슐화하기 때문에 험블 객체가 아니다. 그리고 테스트하기 어려운 부분을 Database 쪽으로 넘겼으니 단위 테스트하기가 용이하다. (Gateway를 stub 이나 test-double로 적당히 교체할 수 있기 때문에)
예시2 : 데이터 매퍼
하이버네이트 같은 ORM은 어느 계층에 속하는가? 물론 데이터베이스 계층이다.
실제로 ORM은 게이트웨이 인터페이스와 데이터베이스 사이에서 일종의 또 다른 험블 객체 경계를 형성한다. (테스트하기 어려운 험블객체. 맡은 역할도 크지 않음. → ORM 부분)
예시3 : 서비스 리스너
애플리케이션이 다른 서비스와 반드시 통신해야 한다면, 또는 애플리케이션에서 일련의 서비스를 제공해야 한다면 우리는 여기에서 서비스 경계를 생성하는 험블 객체 패턴을 발견할 수 있을까?
당연함. 외부의 서비스가 험블 객체가 되는 것. 테스트하기 어려운 부분이고 맡은 역할이 인터페이스에 정의된 데이터를 넘겨주는 역할로만 이해하면.
결론
각 아키텍처 경계 마다 경계 가까이 숨어 있는 험블 객체 패턴을 발견할 수 있다. 경계를 넘나드는 통신은 거의 모두 간단한 데이터 구조를 수반할 때가 많고, 대개 그 경계는 테스트하기 어려운 무언가와 테스트하기 쉬운 무언가로 분리된다. ⇒ 전체 시스템의 테스트 용이성을 크게 높일 수 있다.