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