2.1 네개의 영역

표현, 응용, 도메인, 인프라스트럭처는 아키텍처를 설계할 때 출현하는 전형적인 네 가지 영역이다.

  1. 표현영역은 HTTP 요청을 응용 영역이 필요로 하는 형식으로 변환해서 응용 영역에 전달하고 응용 영역의 응답을 HTTP 응답으로 변환하여 전송한다.
  2. 응용영역은 로직을 직접 수행하기보다는 도메인 모델에 로직 수행을 위임한다.
  3. 도메인 영역에는 도메인 모델을 구현한다. 도메인 모델은 도메인의 핵심 로직을 구현한다.
  4. 인프라스트럭처 영역은 RDBMS 연동 처리나 메시징 큐에 메시지를 전송하거나 수신하는 구현 기술에 대한 것을 다룬다.

2.2 계층 구조 아키택처

Untitled

계층 구조는 그 특성상 상위 계층에서 하위 계층으로의 의존만 존재하고 하위 계층은 상위 계층에 의존하지 않는다.

계층 구조를 엄격하게 적용한다면 상위 계층은 바로 아래의 계층에만 의존을 가져야 하지만 구현의 편리함을 위해 계층 구조를 유연하게 적용하기도 한다. 예를 들어 응용 계층은 바로 아래 계층인 도메인 계층에 의존하지만 외부 시스템과의 연동을 위해 더 아래 계층인 인프라스트럭처 계층에 의존하기도 한다.

Untitled

하지만, 응용영역에서 직접 인프라 스트럭처 계층에 의존을 하면 테스트 어려움과 기능 확장의 어려움이라는 문제가 발생한다.

2.3 DIP

저수준 모듈이 고수준 모듈에 의존하도록 바꾸면 두 가지의 문제가 해결된다. 저수준 모듈이 고수준 모듈에 의존하도록 하려면 인터페이스를 이용하여야 한다.

public interface RuleDiscounter {
	public Money applyRules(Customer customer, List<OrderLine> orderLines);
}
public class CalculateDiscountService {
	private RuleDiscounter ruleDiscounter;

	public CalculateDiscountService(RuleDiscounter ruleDiscounter) {
		this.ruleDiscounter = ruleDiscounter;
	}

	public Money calculateDiscount(OrderLine orderLines, String customerId) {
		Customer customer = customerRepository.findCusotmer(customerId);
		return ruleDiscounter.applyRules(customer, orderLines);
	}
}

CalculateDiscountService에는 Drools에 의존하는 코드가 없다. 단지 RuleDiscounter가 룰을 적용한다는 사실만 알뿐이다. 실제 RuleDiscounter의 구현 객체는 생성자를 통해서 전달받는다.