답변:
최근에 DDD를 읽었습니다. 이 섹션에 도착했을 때, 나는 Evans가했던 것과 동일한 4 계층 아키텍처를 발견했다는 사실에 놀랐습니다. @lonelybug가 지적했듯이 도메인 계층은 나머지 시스템과 완전히 분리되어야합니다. 그러나 UI 고유 값 (쿼리 문자열, POST 데이터, 세션 등)을 도메인 객체로 변환해야합니다. 응용 프로그램 계층이 사용됩니다. UI, 데이터 계층 및 도메인간에 앞뒤로 변환하여 나머지 시스템에서 도메인을 효과적으로 숨기는 것이 중요합니다.
거의 모든 논리가 컨트롤러에있는 많은 ASP.NET MVC 응용 프로그램을 볼 수 있습니다. 고전적인 3 계층 아키텍처를 구현하려는 시도가 실패했습니다. UI 관련 문제가 너무 많기 때문에 컨트롤러를 단위 테스트하기가 어렵습니다. 실제로 "Http Context"값에 직접 관련되지 않도록 컨트롤러를 작성하는 것은 그 자체로 심각한 도전입니다. 이상적으로, 컨트롤러는 번역을 수행하고 작업을 조정하며 응답을 되돌려 놓아야합니다.
응용 프로그램 계층에서 기본 유효성 검사를 수행하는 것이 좋습니다. 도메인에서 값이 의미가 있다고 가정해도 괜찮습니다 (이 고객에게는 유효한 ID이며이 문자열은 날짜 / 시간을 나타냅니다). 그러나 비즈니스 로직과 관련된 유효성 검사 (과거 비행기 티켓을 예약 할 수 있습니까?)는 도메인 계층에 예약되어 있어야합니다.
Martin Fowler는 실제로 오늘날 대부분의 도메인 레이어가 얼마나 평탄한 지에 대해 언급합니다 . 대부분의 사람들은 응용 프로그램 계층이 무엇인지조차 모르지만 많은 사람들이 다른 도메인 개체의 작업을 조정하는 멍청한 도메인 개체와 복잡한 응용 프로그램 계층을 만듭니다. 나 자신이 유죄입니다. 중요한 것은 어떤 책이 당신에게 말했기 때문에 레이어를 만드는 것이 아닙니다. 아이디어는 책임을 식별하고 해당 책임에 따라 코드를 분리하는 것입니다. 필자의 경우 "응용 프로그램 계층"은 단위 테스트를 늘리면서 자연스럽게 진화했습니다.
Martin Fowler의 엔터프라이즈 디자인 패턴에서 가장 일반적인 계층은 다음과 같습니다.
프리젠 테이션-애플리케이션에 대한 상호 작용 인터페이스를 생성하는보기, 프리젠 테이션 템플리트입니다 (웹 서비스 또는 RMI를 통해 다른 시스템에서 애플리케이션에 액세스하여 사용자 인터페이스가 아닐 수있는 경우에 상호 작용을 사용하고 있습니다). 여기에는 작업 실행 방법과 방법을 결정하는 컨트롤러도 포함됩니다.
도메인-비즈니스 규칙과 논리가 상주하고 도메인 모델이 정의되는 위치입니다.
데이터 소스-데이터 맵핑 계층 (ORM) 및 데이터 소스 (데이터베이스, 파일 시스템 등)
세 레이어 사이의 경계를 그리는 방법은 무엇입니까?
모델 또는 도메인 객체 내에 프리젠 테이션 특정 로직을 넣지 마십시오.
페이지와 컨트롤러 내에 로직을 넣지 마십시오. 즉, 데이터베이스에 객체를 저장하고 데이터베이스 연결을 생성하는 로직을 사용하면 프리젠 테이션 레이어가 깨지기 쉽고 테스트하기가 어렵습니다.
모델에서 데이터 소스 액세스와 조치를 분리 할 수있는 ORM을 사용하십시오.
지방 모델 패러다임을 따르십시오. 컨트롤러는 실행 프로세스를 수행하지 않는 제어 프로세스를위한 것입니다 . 및 http://weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-model 모델, 뷰 및 컨트롤러,
도메인 계층 모델링 비즈니스 응용 프로그램의. 이것은 규칙에 대한 명확한 해석, 구성 요소 역학 및 주어진 시점의 상태를 포함해야합니다.
응용 프로그램 계층은 특정 응용 프로그램의 작업을 수행 할 필요가 작업을 정의하는 "걱정"입니다. 주로 필요한 도메인 작업을 위임하고 다른 서비스 (외부 또는 비 서비스) 와 상호 작용합니다.
예를 들어 , 재무 소프트웨어 응용 프로그램에는 모델 엔터티 (DDD [89]에 정의 된 엔터티)의 상태를 변경하는 사용자 작업이 있습니다.
그러나 응용 프로그램 프로세스 로서이 작업의 모든 모델 결과 외에도 응용 프로그램의 다른 사용자에게 내부 통신을 보내야합니다. 이러한 종류의 작업은 응용 프로그램 계층에서 "조정됩니다". 도메인 서비스에서 메시징 서비스를 지시하는 것을 원하지 않습니다. (그리고 이것은 확실히 표현 계층 책임이 아닙니다). 어쨌든 한 가지 확실한 점은 도메인 레이어가 핵심 비즈니스에 관한 것이고 프레젠테이션 레이어는 사용자 명령을 해석하고 결과를 제시하는 것이므로 새 레이어가 필요합니다.
노트:
도메인 계층은 격리 계층으로 설계해야합니다. 즉, 비즈니스 로직과 규칙은 코드 (응용 프로그램 계층, 프레젠테이션 계층 및 인프라 계층) 변경에 영향을받지 않아야합니다.
응용 프로그램 계층은 시스템 (응용 프로그램) 인터페이스 (API 또는 RESTful처럼 생각)가 수행 할 수있는 기능에 대한 일부 기능을 제공하도록 설계되었다고 가정합니다. 예를 들어, 사용자는 시스템에 로그인 할 수 있으며이 응용 프로그램 작업 (로그인)에서 응용 프로그램 계층 코드는 도메인 계층 (또는 인프라 계층)의 클라이언트 코드가됩니다.이 코드는 사용자 도메인 개체를 검색하고이 개체의 메서드를 적용하여 '로그인'기능.
응용 프로그램 계층은 격리 계층으로 설계되어야합니다. 즉, 응용 프로그램의 동작이 코드 (프레젠테이션 계층, 도메인 계층 및 인프라 계층) 변경에 영향을받지 않아야합니다.
도메인 기반 모델링의 핵심 은 필수 도메인 모델 을 분리하여 다른 계층 및 기타 응용 프로그램 문제에 대한 종속성없이 존재하도록하는 것입니다.
이를 통해 방해 요소없이 도메인 자체에 집중할 수 있습니다 (예 : UI와 지속성 서비스 간의 조정).
이러한 경계의 주된 이유 는 우려의 분리 때문입니다 . 데이터 저장소에 액세스하는 코드는 데이터 저장소에 액세스 할 때만 걱정하면됩니다. 데이터에 규칙을 시행 할 책임이 없습니다. 또한 UI는 UI의 컨트롤을 업데이트하고, 사용자 입력에서 값을 가져 와서 도메인 레이어가 사용할 수있는 것으로 변환하는 역할을합니다. 필요한 작업을 수행하기 위해 도메인 계층에서 제공하는 작업을 호출해야합니다 (예 :이 파일 저장). 호출되는 웹 서비스는 전송 매체에서 도메인 계층이 사용할 수있는 것으로 변환 한 다음 도메인 계층을 호출해야합니다 (대부분의 도구는이 작업을 많이 수행합니다).
이러한 분리를 올바르게 구현하면 다른 부분에 영향을주지 않고 코드의 일부를 변경할 수 있습니다. 예를 들어, 리턴 된 오브젝트 콜렉션의 정렬 순서를 변경해야 할 수도 있습니다. 데이터 조작을 담당하는 계층 (일반적으로 비즈니스 논리 계층)이이 항목을 처리한다는 것을 알고 있으므로 코드를 변경해야하는 위치를 쉽게 식별 할 수 있습니다. 뿐만 아니라 데이터 저장소 또는 도메인을 사용하는 응용 프로그램 (위의 예제에서 UI 및 웹 서비스)에서 검색하는 방법을 수정할 필요가 없습니다.
궁극적 인 목표는 코드를 최대한 쉽게 유지 관리하는 것입니다.
참고로, 일부는 도메인의 특정 계층 (예 : 로깅, 유효성 검사 및 권한 부여)으로 비둘기를 cannot 수 없습니다. 이러한 항목은 일반적으로 교차 절단 문제라고하며 경우에 따라 다른 모든 계층에서보고 사용할 수있는 계층으로 간주 될 수 있습니다.
개인적으로 나는 계층 적 접근 방식이 구식이며 서비스 접근 방식이 더 좋다고 생각합니다. 누가 무엇을 하는가에 대해 여전히 모래에 뚜렷한 선이 그려져 있지만, 그것이 당신을 계층 적으로 강요하지는 않습니다. 예를 들어, 구매 주문 서비스, 청구 서비스 및 운송 서비스는 응용 프로그램 관점에서 이러한 모든 서비스가 귀하의 도메인을 대표하며 위에서 설명한 책임의 유예는 여전히이 맥락에서 유효합니다. 도메인이 여러 곳에 존재하므로 우려 분리 개념을 더 활용합니다.