04 - 도메인의 격리

LAYERED ARCHITECTURE (계층형 아키텍처)

관심사 분리가 필요한 이유

  • 객체지향 프로그램에서는 종종 UI 와 DB, 기타 보조적인 성격의 코드를 비지니스 객체 안에 직접 작성하기도 한다.

  • 이런 일이 발생하는 이유는, 단기적으로는 위 방법이 뭔가를 동작하게 하는 가장 쉬운 방법이기 때문이다.

  • 도메인에 관련된 코드가 상당한 양의 도메인과 관련이 없는 다른 코드를 통해 널리 확산될 경우, 도메인에 관련된 코드를 확인하고 추론하기가 굉장히 힘들어진다.. (복잡도가 올라간다는 소리)

  • 기술과 로직이 모두 각 활동에 포함돼 있다면 프로그램을 매우 단순하게 유지해야 하며, 그렇지 않으면 이해하기가 불가능에 가까워진다.. (회사 코드를 생각해보자 .. 이해불가 ;;)

  • 그렇기 때문에 관심사 분리를 해야한다!

LAYERED ARCHITECTURE (관심사 분리의 방법)

  • 많은 관례와 경험을 바탕으로 널리 받아들여지는 계층화는 어느정도 정해졌다. (메인은 도메인 계층에 있다)

  • 결론적으로 복잡한 프로그램을 여러 계층으로 나눠라!

  • 응집력 있고 오직 아래에 위치한 계층에만 의존하는 각 계층에서 설계를 발전시켜라.

  • 도메인과 관련된 코드는 모두 한 계층에 모으고 사용자 인터페이스 코드나 어플리케이션 코드, 인프라스트럭처 코드와 격리하라.

계층1 - 사용자 인터페이스 계층

  • 사용자 화면을 구성하는 것에 관심이 있습니다.

  • 사용자 인터페이스를 어떻게 구성하고 상호 작용은 어떻게 수행할지에 대한 책임을 가지고 있습니다.

  • 화면을 직접 서비스하지 않는다면 클라이언트로부터 요청을 받고, 응답하는 API를 정의합니다.

계층2 - 어플리케이션 계층

  • 도메인 계층의 비즈니스 로직과 인프라스트럭처 계층의 데이터 접근 로직을 조율하는 것에 관심이 있습니다.

  • 실제 비즈니스 로직보단 고수준(high-level)에서 추상화 된 어플리케이션 기능을 표현합니다.

계층3 - 도메인 계층

  • 핵심 비즈니스 로직을 수행하는 것에 관심이 있습니다.

  • 세부적인 기술이나 외부 관심사에 의존하지 않고, 격리된 상태에서 순수한 비즈니스 로직을 수행합니다.

  • Java 어플리케이션인 경우에 POJO(Plain Old Java Object) 객체를 사용해 비즈니스 로직을 구성합니다.

계층4 - 인프라스트럭처 계층

  • 상위 계층에게 기술적인 부분을 지원하는 것에 관심이 있습니다.

  • 기술 종속성이 강한 구현체를 제공하는 계층입니다.

  • 영속성 프레임워크, 프레임워크 설정, 외부 API 요청 기능, 이벤트 리스너(listener) 등이 있습니다.

예제 (온라인 뱅킹 기능을 여러 계층으로 나누기)

  • 어떤 애플리케이션에서 은행 계좌를 유지하는 데 필요한 다양한 기능을 제공하고 있다. 그 중 하나가 바로 사용자가 두 계좌번호와 일정 금액을 입력하면 이체가 시작되는 자금 이체 기능이다.

  • 여기서 눈여겨봐야 할 것은 어플리케이션 계층이 아닌 도메인 계층에서 주요 업무 규칙을 책임지고 있다는 것이며, 이 경우 모든 debit 에는 대응되는 credit 가 있다는 것이 업무규칙에 해당한다.

  • 이 애플리케이션에서는 누가 송금을 요청했는가에 관해서는 아무런 가정도 하지 않는다. 아마 프로그램에는 계좌번호와 금액을 입력하는 필드와 명령 버튼이 포함된 사용자 인터페이스가 있을 것이다.

  • 하지만 그와 같은 사용자 인터페이스는 어플리케이션 계층이나 그 아래의 계층에는 영향을 주지 않는 다른 형식의 송금 요청으로 대체될 수도 있다.

  • 이 같은 분리가 중요한 까닭은 프로젝트에서 사용자 인터페이스를 자주 대체해야 하기 때문이 아니라 깔끔한 관심사의 분리를 토대로 각 계층의 설계를 이해하고 유지하기가 쉬워지기 때문이다.

계층 간 관계 설정

  • 지금까지 계층의 분리와 그러한 분할 방법 가운데 어떤 것이 프로그램의 각 측면, 특히 도메인 계층의 설계를 향상시키는지 집중적으로 살펴 보았다.

  • 그럼에도 당연히 각 계층은 서로 연결되어야 한다. 분리의 이점을 잃지 않으면서 각 계층을 서로 연결하는 것이야말로 각종 패턴이 존재하는 이유이다. (느슨한 결합)

    • 각 계층은 설계 의존성을 오직 한 방향으로만 둬서 느슨하게 결합된다.

  • 어플리케이션 계층과 도메인 계층에 UI 를 연결하는 패턴은 MVC(Model-View-Controller) 에서 유래한다.

    • UI 와 애플리케이션을 연결하는 것과 관련된 다른 유형의 접근법도 있다.

    • 하지만 논의의 목적상 도메인 계층을 격리해서 해당 도메인 객체를 설계할 때 동시에 사용자 인터페이스도 생각할 필요가 없게 만들어준다면 어떤 접근법도 괜찮다.

  • 보통 인프라스트럭처 계층에서는 도메인 계층에서 어떤 활동이 일어나게 하지 않는다.

    • 인프라스트럭처 계층은 도메인 계층 아래에 있으므로, 해당 인프라스트럭처 계층이 보조하는 도메인의 구체적인 지식을 가져서는 안된다.

    • 이를테면, 어떤 애플리케이션에서 이메일을 전송해야 한다면 메시지 전송 인터페이스가 인프라스트럭처 계층에 위치할수 있으며, 애플리케이션 계층에 각 요소는 인프라스트럭처 계층에 메시지 전송을 요청할 수 있다.

  • 이러한 계층 분리는 어느 정도 융통성을 제공한다.

    • 메시지 전송 인터페이스는 이메일 송신기나 팩스 송신기, 또는 다른 사용할 수 있는 어떤 것에도 연결될 수 있다.

    • 그러나 분리의 주된 이점은 애플리케이션 각각의 계층이 단순해져서 애플리케이션 본연의 책임에만 집중하게 되는 것이며, 이로써 "언제" 보내는지는 알아도 "어떻게" 보내는지 알 필요가 없어진다.

Last updated