문제

세부 사항이 많지 않은 도메인 구동 설계의 한 부분은 인터페이스에서 도메인 모델을 어떻게 분리 해야하는지입니다. 동료들에게 이것이 좋은 관행이라고 확신 시키려고 노력하고 있지만 많은 진전을 이루지 않는 것 같습니다 ...

그들은 프레젠테이션 및 인터페이스 계층에서 원하는 곳에 도메인 엔티티를 사용합니다. 인터페이스 계층에서 도메인 계층을 단열하기 위해 디스플레이 모델 또는 DTO를 사용해야한다고 주장 할 때, 그들은 비즈니스 가치가 그런 일을하는 데있어 비즈니스 가치가 보이지 않는다고 주장합니다. 원래 도메인 객체뿐만 아니라.

그래서 나는 이것을 백업하는 데 사용할 수있는 몇 가지 구체적인 이유를 찾고 있습니다. 구체적으로:

  1. 프레젠테이션 계층에서 도메인 객체를 사용해서는 안되는 이유는 무엇입니까?
    (대답이 명백한 '분리'라면, 이것이이 맥락에서 왜 중요한지 설명하십시오)
  2. 인터페이스에서 도메인 객체를 분리하기 위해 추가 객체 나 구조물을 사용해야합니까?
도움이 되었습니까?

해결책

간단히 말해서 그 이유는 구현과 드리프트 중 하나입니다. 예, 프레젠테이션 계층은 비즈니스 개체에 대해 알아야합니다. 예, 처음에는 두 유형의 객체의 구현 사이에 많은 겹치는 것처럼 보입니다. 문제는 시간이 지남에 따라 양쪽에 추가되는 것입니다. 프리젠 테이션 변경 및 프레젠테이션 계층의 요구는 비즈니스 계층과 완전히 독립적 인 것들 (예 : 색상)을 포함하도록 발전합니다. 한편, 도메인 객체는 시간이 지남에 따라 변경되며 인터페이스에서 적절한 분리가 없으면 비즈니스 객체를 겉보기에 양성으로 변경하여 인터페이스 계층을 조일 위험이 있습니다.

개인적으로, 나는 사물에 접근하는 가장 좋은 방법은 엄격하게 시행 된 인터페이스 패러다임을 통한 것이라고 생각합니다. 즉, 비즈니스 객체 계층은 커뮤니케이션 할 수있는 유일한 방법 인 인터페이스를 노출시킵니다. 인터페이스에 대한 구현 세부 사항 (예 : 도메인 개체)은 노출되지 않습니다. 예, 이것은 두 위치에서 도메인 객체를 구현해야 함을 의미합니다. 인터페이스 레이어와 BO 레이어. 그러나 그 상환은 처음에는 추가 작업처럼 보일지 모르지만 미래의 어느 시점에서 수많은 작업을 절약 할 수있는 분리를 시행하는 데 도움이됩니다.

다른 팁

나는 이것에 어려움을 겪었다. DTO가 PRESINATON에서 사용하는 것이 합리적 인 경우가 있습니다. 내 시스템에 회사의 드롭 다운을 보여주고 싶다고 가정 해 봅시다. 가치를 바인딩하려면 신분증이 필요하다고 가정 해 봅시다.

구독에 대한 참조가 있거나 다른 것을 아는 회사 인구를로드하는 대신 이름과 ID로 DTO를 다시 보낼 수 있습니다. 이것은 IMHO를 잘 사용합니다.

이제 다른 예를 들어보세요. 나는 추정치를 나타내는 객체가 있고,이 추정치는 노동, 장비 등을 구성 할 수 있으며, 이러한 모든 항목을 가져 와서 요약하는 사용자가 정의하는 많은 계산이있을 수 있습니다 (각 추정치는 다른 유형과 다를 수 있습니다. 계산). 이 개체를 두 번 모델링 해야하는 이유는 무엇입니까? 왜 단순히 UI가 계산을 열거하고 표시 할 수 없습니까?

나는 일반적으로 DTO를 사용하여 내 UI에서 내 도메인 레이어를 분리하지 않습니다. 나는 그것들을 사용하여 내 컨트롤을 벗어난 경계에서 내 도메인 레이어를 분리합니다. 누군가가 자신의 비즈니스 객체에 내비게이션 정보를 넣을 것이라는 생각은 말도 안되며 비즈니스 대상을 오염시키지 마십시오.

누군가가 비즈니스 대상에 검증을 할 것이라는 생각? 글쎄, 나는 이것이 좋은 것이라고 말한다. UI는 비즈니스 개체를 검증할만한 책임이 없어야합니다. 귀하의 비즈니스 계층 해야 하다 자체 검증을 수행하십시오.

왜 UI 생성 코드를 Busienss 개체에 넣으십니까? 제 경우에는 UI에서 UI 코드 Seperatley를 생성하는 별도의 객체가 있습니다. 비즈니스 객체를 XML로 만드는 객체가 늘어납니다. 이러한 유형의 오염을 방지하기 위해 레이어를 분리해야한다는 아이디어는 왜 HTML 생성 코드를 비즈니스 개체에 넣을 수 있기 때문에 ...

편집하다조금 더 생각하면 UI 정보가 도메인 계층에 속할 수있는 경우가 있습니다. 그리고 이것은 당신이 도메인 레이어라고 부르는 것을 흐리게 할 수 있지만, 나는 UI 모양과 느낌과 기능적 워크 플로 모두에서 매우 다른 행동을 가진 멀티 테넌트 응용 프로그램에서 작업했습니다. 다양한 요인에 따라. 이 경우 우리는 임차인과 해당 구성을 나타내는 도메인 모델이있었습니다. 그들의 구성에는 UI 정보 (예 : 일반 필드에 대한 레이블)가 포함되어 있습니다.

객체를 지속 가능하게 만들기 위해 객체를 설계해야한다면 객체를 복제해야합니까? 새로운 필드를 추가하려면 지금 두 곳을 추가 할 곳이 있습니다. 아마도 이것은 당신의 DDD를 사용하는 것이 모두 지속 된 엔티티 도메인 객체 인 경우 또 다른 질문을 제기 할 수 있습니까? 나는 내 예에서 그들이 있다는 것을 알고 있습니다.

당신은 당신이 당신의 ASP/JSP 페이지에서 SQL을 유지하는 것과 같은 이유로 그것을합니다.

프레젠테이션 및 도메인 계층에 사용하기 위해 하나의 도메인 객체 만 유지하면 해당 객체가 곧 모 놀리식이됩니다. UI 검증 코드, UI Navigation Code 및 UI Generation Code가 포함되기 시작합니다. 그런 다음 곧 모든 비즈니스 계층 방법을 추가합니다. 이제 귀하의 비즈니스 계층과 UI가 모두 혼합되어 있으며 모두 도메인 엔티티 레이어에서 엉망이됩니다.

다른 앱에서 그 멋진 UI 위젯을 재사용하고 싶습니까? 글쎄, 당신은이 이름,이 두 스키마 및 18 개의 테이블이있는 데이터베이스를 만들어야합니다. 또한 비즈니스 검증을 수행하려면 최대 절전 모드 및 스프링 (또는 선택한 프레임 워크)을 구성해야합니다. 오, 당신은 또한 비즈니스 계층에서 참조되기 때문에이 85 개의 다른 비 관련 클래스도 포함해야합니다.

나는 동의하지 않는다.

가장 좋은 방법은 프레젠테이션 계층의 도메인 객체로 시작하는 것이 그렇지 않으면 이해가 될 때까지 시작하는 것입니다.

대중의 믿음과는 달리, "도메인 객체"및 "값 객체"는 프레젠테이션 계층에서 행복하게 공존 할 수 있습니다. 그리고 이것이 가장 좋은 방법입니다. 두 세계의 이점을 얻을 수 있습니다. 도메인 객체와의 복제 (및 보일러 플레이트 코드)가 줄어 듭니다. 요청에 걸쳐 가치 객체를 사용하는 재단 및 개념 단순화.

서버와 UI에서 동일한 모델을 사용하고 있습니다. 그리고 그것은 고통입니다. 우리는 언젠가 그것을 리팩터링해야합니다.

문제는 주로 도메인 모델이 전체 데이터베이스를 참조하지 않고 직렬화 할 수 있도록 작은 조각으로 절단해야하기 때문입니다. 이로 인해 서버에서 사용하기가 더 어려워집니다. 중요한 링크가 누락되었습니다. 일부 유형은 직렬화 할 수 없으며 클라이언트에게 보낼 수 없습니다. 예를 들어 '유형'또는 일반 클래스. 비전자 여야하며 유형은 문자열로 전송되어야합니다. 이것은 직렬화를위한 추가 특성을 생성하며 중복되고 혼란 스럽습니다.

또 다른 문제는 UI의 엔티티가 실제로 맞지 않는다는 것입니다. 우리는 Databinding을 사용하고 있으며 많은 엔티티는 UI 목적으로 만 많은 중복 속성을 가지고 있습니다. 또한 엔티티 모델에는 많은 'browsableattribute'와 다른 사람들이 있습니다. 이것은 정말 나쁘다.

결국, 나는 그것이 어느 방식이 더 쉬운 일이라고 생각합니다. 잘 작동하고 다른 DTO 모델을 작성할 필요가없는 프로젝트가있을 수 있습니다.

답변은 응용 프로그램 규모에 따라 다릅니다.


간단한 crud (생성, 읽기, 업데이트, 삭제) 응용 프로그램

기본 CRUD 응용 프로그램의 경우 기능이 없습니다. 엔티티 위에 DTO를 추가하는 것은 시간을 낭비합니다. 확장 성을 증가시키지 않으면 서 복잡성을 증가시킵니다.

enter image description here


적당히 복잡한 비 심수 응용 프로그램

이 크기의 애플리케이션에는 진정한 수명주기가있는 엔티티와 그와 관련된 비즈니스 논리가 거의 없습니다.

이 경우에 DTOS를 추가하는 것은 몇 가지 이유로 좋은 생각입니다.

  • 프레젠테이션 계층은 엔티티가 가지고있는 필드의 하위 집합 만 볼 수 있습니다. 엔티티를 캡슐화합니다
  • 백엔드와 프론트 사이의 커플 링이 없습니다
  • 엔티티 내부에 비즈니스 방법이 있지만 DTO에 있지 않은 경우 DTOS를 추가하면 외부 코드가 엔티티의 상태를 망칠 수 없습니다.

enter image description here


복잡한 엔터프라이즈 응용 프로그램

단일 엔티티에는 여러 가지 프레젠테이션이 필요할 수 있습니다. 그들 각각은 다른 필드 세트가 필요합니다. 이 경우 이전 예제에서와 동일한 문제가 발생하면 각 클라이언트에 대해 볼 수있는 필드의 양을 제어해야합니다. 각 클라이언트에 대해 별도의 DTO가 있으면 보이는 것을 선택하는 데 도움이됩니다.

enter image description here

그것은 대부분 의존성에 관한 것입니다. 조직의 핵심 기능 구조에는 고유 한 기능 요구 사항이 있으며 UI는 사람들이 핵심을 수정하고 볼 수 있어야합니다. 그러나 핵심 자체는 UI를 수용 할 필요가 없어야합니다. (발생 해야하는 경우 일반적으로 핵심이 속성이 설계되지 않았다는 표시입니다.)

내 회계 시스템에는 회사의 운영을 모델링 해야하는 구조 및 컨텐츠 (및 데이터)가 있습니다. 그 구조는 실제이며 내가 사용하는 계정 소프트웨어에 관계없이 존재합니다. (필연적으로 주어진 소프트웨어 패키지에는 자체적으로 구조와 컨텐츠가 포함되어 있지만 문제의 일부는이 오버 헤드를 최소화하는 것입니다.)

기본적으로 사람은 할 일이 있습니다. DDD는 작업의 흐름과 내용과 일치해야합니다. DDD는 가능한 한 완전하고 독립적으로 수행 해야하는 모든 작업을 명시 적으로 만드는 것입니다. 그런 다음 UI는 가능한 한 생산적으로 가능한 한 투명하게 작업을 수행하는 것을 희망적으로 촉진합니다.

인터페이스는 올바르게 모델링되고 불변 기능적인 기능 코어를 위해 제공된 입력 및 뷰에 관한 것입니다.

젠장, i 욕을 하다 이것은 끈기를 말했다.

어쨌든, 그것은 똑같은 사례입니다. Parnas의 법칙에 따르면 모듈은 비밀을 유지해야하며 비밀은 변화 할 수있는 요구 사항이라고 말합니다. (Bob Martin은 이것의 또 다른 버전 인 규칙이 있습니다.) 이와 같은 시스템에서 프레젠테이션 독립적으로 변할 수 있습니다 도메인. 예를 들어, 유로로 가격을 유지하고 회사 사무실에서 프랑스어를 사용하지만 만다린의 텍스트와 함께 달러로 가격을 제시하려는 회사와 같은 회사와 같이. 그만큼 도메인 는 똑같은; 프레젠테이션이 변경 될 수 있습니다. 따라서 시스템의 브리틀즈, 즉 요구 사항 변경을 구현하기 위해 변경해야 할 사항의 수를 최소화하기 위해 우려 사항을 분리합니다.

당신의 프레젠테이션은 할 수 있습니다 참조 도메인 계층이지만 UI에서 도메인 객체에 직접 바인딩되지 않아야합니다. 도메인 객체는 데이터 표현이 아닌 동작을 기반으로 적절하게 설계된 경우 종종 UI 사용을위한 것이 아닙니다. UI와 도메인 사이에 매핑 레이어가 있어야합니다. MVVM 또는 MVP는 이에 대한 좋은 패턴입니다. UI를 도메인에 직접 묶으려고하면 Probalby가 스스로 두통을 많이 듭니다. 그들은 두 가지 다른 목적을 가지고 있습니다.

아마도 당신은 충분히 광범위한 용어로 UI 계층을 개념화하지 않을 것입니다. 여러 형태의 응답 (웹 페이지, 음성 응답, 인쇄 문자 등) 및 여러 언어 (영어, 프랑스어 등) 측면에서 생각하십시오.

이제 전화 통화 시스템의 음성 엔진이 웹 사이트 (Windows)를 실행하는 컴퓨터에서 완전히 다른 유형의 컴퓨터 (예 : Mac)에서 실행된다고 가정합니다.

물론 "우리 회사에서는 영어에만 관심이 있고, 램프 (Linux, Apache, MySQL 및 PHP)에서 웹 사이트를 실행하며 모든 사람이 동일한 버전의 Firefox를 사용하기 쉽습니다. 그러나 5 년 또는 10 년 만에 어떻습니까?

다음에서 "계층 간의 데이터 전파"섹션도 참조하십시오. 이는 설득력있는 주장을 제시한다고 생각합니다.

http://galaxy.andromda.org/docs/andromda-documentation/andromda-getting-started-java/java/index.html

도구의 도움으로 '가치 부상프레젠테이션 계층에서 '매퍼'의 개념은보기로 작업하는 동안 각 코드를 이해하는 것이 훨씬 쉽습니다. 약간의 코드가 있으면 즉시 장점을 보지 못하지만 프로젝트가 점점 더 커지면 서비스의 논리를 입력 할 필요가없는 견해로 작업하는 동안 매우 행복 할 것입니다. 뷰 모델을 이해하기위한 저장소. View Model은 반부패 방지 층의 광대 한 세계에서 또 다른 가드이며 장기 프로젝트에서 금으로 무게를 가질 가치가 있습니다.

View 모델을 사용하는 것이 장점이없는 유일한 이유는 프로젝트가 작고 단순한 경우 뷰가 모델의 각 속성에 직접 뷰를 뿌릴 정도로 간단한 경우입니다. 그러나 미래에, 뷰의 요구 사항 변경 및 일부 컨트롤이 모델에 얽히지 않고 View 모델 개념이 없으면 여러 곳에서 패치를 추가하기 시작하면 레거시 코드를 갖기 시작합니다. 당신은 감사하지 않을 것입니다. 물론, 당신은 뷰-모델에서 뷰 모델을 변환하기 위해 refactoring을 수행하고 Yagni 원칙을 따르고 코드를 추가하지 않으면 서 코드를 추가하지 않으면 나 자신을 위해서는 다음을 추가하기 위해 따라야 할 모범 사례입니다. 프리젠 테이션 계층은 뷰 모델 객체 만 노출됩니다.

다음은 도메인 엔티티를보기에서 분리하는 것이 좋은 관행을 찾는 이유에 대한 실제 예입니다.

몇 달 전에 나는 일련의 3 개의 게이지를 통해 토양 샘플에서 질소, 인 및 칼륨의 값을 보여주는 간단한 UI를 만들었습니다. 각 게이지에는 빨간색, 녹색 및 빨간색 섹션이있었습니다. 즉, 각 구성 요소의 너무 적거나 너무 적을 수는 있지만 중간에는 안전한 녹색 레벨이있었습니다.

많은 생각없이, 나는 비즈니스 로직을 모델링 하여이 3 가지 화학 구성 요소와 별도의 데이터 시트에 대한 데이터를 공급하여 3 가지 경우 각각의 수용된 수준에 대한 데이터를 포함합니다 (사용되는 측정 단위, 즉 두더지 또는 백분율 포함). 그런 다음 매우 다른 모델을 사용하기 위해 UI를 모델링했습니다.이 모델은 게이지 레이블, 값, 경계 값 및 색상과 관련이있었습니다.

이것은 나중에 12 개의 구성 요소를 보여 주어야 할 때 추가 데이터를 12 개의 새로운 게이지보기 모델에 매핑했으며 화면에 나타났습니다. 또한 게이지 컨트롤을 쉽게 재사용하고 다른 데이터 세트를 표시 할 수 있음을 의미했습니다.

이 게이지를 도메인 엔티티에 직접 연결했다면 위의 유연성이 없으며 향후 수정은 두통이 될 것입니다. UI에서 캘린더를 모델링 할 때 매우 유사한 문제를 발견했습니다. 참석자 10 명 이상이있을 때 달력 약속이 빨간색으로 바뀌어야하는 요구 사항이있는 경우,이를 처리하려는 비즈니스 논리는 비즈니스 계층에 남아 있어야하며 UI의 모든 달력은 알아야합니다. 빨간색으로 돌리면 이유를 알 필요가 없습니다.

일반화와 도메인 별 시맨틱 사이에 추가 매핑을 추가하는 유일한 현명한 이유는 도메인 시맨틱과 구별되는 일반화 된 (그러나 맵핑 가능한) 시맨틱을 기반으로하는 기존 코드 (및 도구)에 액세스하기 때문입니다.

도메인 구동 설계는 직교 기능 도메인 프레임 워크 (ORM, GUI, 워크 플로 등)와 함께 사용될 때 가장 잘 작동합니다. 도메인 의미론을 노출해야한다는 것은 외부 층 인접에만 있었다는 것을 항상 기억하십시오. 일반적으로 이것은 프론트 엔드 (GUI) 및 영구 백엔드 (RDBM, ORM)입니다. 효과적으로 설계된 중재 층은 도메인 변하지 않아야합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top