엄격한 TDD와 DDD를 결합하는 방법?


15

TDD는 테스트를 통해 코드를 디자인하는 것입니다.
따라서 일반적인 레이어는 일반적으로 사전에 구축되지 않습니다. 리팩토링 단계를 통해 약간 나타나야합니다.

도메인 기반 설계에는 응용 프로그램 계층, 인프라 계층, 도메인 계층, 지속성 계층과 같이 잘 설정된 계층을 정의하는 많은 기술적 패턴이 포함됩니다.

DDD 프로젝트의 코딩 부분을 처음부터 시작하려면 어떻게해야합니까?
DDD 기술 패턴에 맞추기 위해 디자인이 테스트에서 엄격하게 드러나도록해야합니까?

아니면 빈 레이어 (응용 프로그램, 엔터티 / 도메인 서비스, 인프라)를 만들고 TDD가 각 레이어에 독립적으로 맞도록해야합니까 (모의를 사용하여 레이어 간 격리)?


답변:


12

TDD에서 디자인 의 역할에 대한 Bob 아저씨의 최근 의견을 검토하십시오 .

도메인 기반 설계에는 응용 프로그램 계층, 인프라 계층, 도메인 계층, 지속성 계층과 같이 잘 설정된 계층을 정의하는 많은 기술적 패턴이 포함됩니다.

Udi Dahan : "하나님, 레이어링이 싫습니다." 그는 대화 CQRS 에서 시간을 보내고 있지만 다릅니다 (계층화는 18m30 초에 시작).

나는 당신의 문장을 약간 다르게 철자 할 것입니다. "DDD는 대부분의 비즈니스 응용 프로그램에 공통적 인 여러 가지 문제가 있으며 해당 문제에 대한 솔루션의 수명이 서로 다르다는 것을 알고 있습니다. "

예를 들어 도메인 문제는 일반적으로 융통성이 있어야합니다. 특히 특정 비즈니스에 대한 솔루션을 사용자 정의 할 때 더욱 그렇습니다. 결국, 도메인은 회사의 비즈니스 운영 방식, 즉 회사가 어떻게 돈을 벌고 비즈니스 개선을 신속하게 제공 할 수 있는지에 관한 것입니다.

반면에 지속성 구성 요소를 자주 변경할 필요는 없습니다. 마지막 릴리스에서 작동 한 데이터베이스 솔루션도이 릴리스에서 작동합니다.

응용 프로그램 문제는 중간에 있습니다. 사용자는 매번 릴리스 할 때마다 새로운 앱을 배울 필요가 없도록 안정적인 경향이 있습니다.

또한 주어진 관심사를 해결하기 위해 여러 가지 구현이있을 수 있습니다. 예를 들어, 응용 프로그램은 현재 상태의 스냅 샷 만 필요할 수 있습니다. 파일을 디스크에 저장하면 충분합니다. 그리고 처음 몇 번의 반복에서는 모든 도메인에 필요한 것일 수도 있습니다. 그러나 결국에는 임시 쿼리 지원이 필요하다는 이야기가 나오며 관계형 데이터베이스 구성이 처음부터 구현하는 것보다 훨씬 쉽다는 것을 알고 있습니다. 그리고 그래프 데이터베이스에서 더 잘 작동하는이 기능이 있습니다.

한편 CTO는 휴대 전화에서 실행되는 앱 버전을 원합니다. CEO가 방금 API를 게시하는 것이 큰 일이라고 들었습니다.

또한 영업 팀은 다른 모델을 사용하므로 다른 모델의 동일한 앱을 제공하십시오. 아, 그러나 우리는 많이 여행하고 있으므로 오프라인 상태에서 나중에 동기화 할 때 버전이 작동해야합니다 ...

즉, 빈 자리 표시자를 구현하고 나중에 채워질 것이라고 가정하지 않고 의 전술 패턴을 적용합니다. 대신 스트림을 교차 할 때 인식 합니다. 리팩토링을 완료했습니다. "


11

TDD (Test Driven Development) 는 디자인이 아닙니다. 디자인에 영향을 미치는 요구 사항입니다. 마치 스레드 안전해야하는 것처럼 디자인이 아닙니다. 다시 한 번, 디자인에 영향을 미치는 요구 사항입니다.

다른 모든 디자인 문제를 유쾌하게 무시하고 종교적으로 TDD 규칙을 지키면 코드가 허물어 질 때 TDD를 비난하지 않습니다. 테스트 가능한 쓰레기이지만 쓰레기가 될 것입니다.

테스트 가능한 쓰레기에 대한 한 가지 좋은 점은 리 팩터 블 쓰레기이기 때문에 일부 사람들에게는 충분하다는 것입니다. 우리는 필요할 때만 화려할 것입니다. 다른 사람들은 이것을 싫어하고 TDD를 비난합니다. 아뇨. 당신이하는 일입니다.

도메인 기반 설계 (DDD) 는 TDD의 적색 녹색 리 팩터 사이클 전에 수행하는 작업입니다.

DDD는 시스템의 세부 사항을 잘 모르는 도메인 전문가가 시스템 제어 방법을 이해할 수있는 코드 공간을 만들고 보존하기위한 노력입니다. 이는 익숙한 방식으로 문제 영역을 추상화하고 모델링하여 수행됩니다.

DDD 시스템은 다음과 같은 아키텍처를 가질 수 있습니다.

여기에 이미지 설명을 입력하십시오

이 DDD 아키텍처에는 Clean , Onion , Hexagonal 등 의 많은 이름이 사용됩니다.

이 디자인을 볼 때 많은 사람들이 볼 수있는 단절이 있습니다. 이것은 구체적이지 않습니다. 나는이 디자인을 따를 수 있으며 여기에 다이어그램으로 표시된 것을 쓰지 않았습니다. 다른 사람들은 유스 케이스 객체 또는 엔티티 클래스가 있어야한다고 주장합니다. 이것이 무엇인지는 누구와 대화 할 수 있는지를 알려주는 일련의 규칙입니다.

그게 다야. 이 디자인의 규칙을 따르고 작은 마음을 TDD 할 수 있습니다. TDD는 당신이 누구와 대화하든 상관 없습니다. 버튼을 클릭하면 무언가를 수행하는 모든 것이 작동하는지 여부를 확인할 수 있습니다. 아닙니다, 어딘가에 무언가가 깨졌습니다. 정확히 무엇이 고장 났는지 알려줍니다.

아직도 모호하다? 상기 봐 Controler- Use Case Interactor- Presenter오른쪽 하단 모서리에있는 그림. 서로 통신하는 세 가지 구체적인 사항이 있습니다. 물론 이것이 DDD이지만 여기에 TDD를 어떻게 추가합니까? 구체적인 물건을 조롱하십시오. 발표자는 정보를 받고 있어야합니다. PresenterMock클래스는 당신이 그것을 얻을 것으로 예상 무엇을 얻고 있는지 확인하는 좋은 방법이 될 것입니다. 손 Use Case InteractorPresenterMock하고 드라이브 Use Case Interactor당신이 인 것처럼 Controller당신이 단위 테스트에 좋은 방법을 가지고있는 Use Case Interactor당신이 그것을 얻을 것으로 예상 무엇을 가지고있는 경우 모의가 당신을 말할 것이다 때문이다.

잘보세요 TDD는 만족했으며 DDD 디자인에 관심을 갖지 않아도되었습니다. 어떻게 된거 지? 우리는 잘 분리 된 디자인으로 시작했습니다.

TDD를 사용하여 디자인을 개발 (단순히 개발 하지는 않음 )하면 디자인 노력을 반영한 디자인을 얻게됩니다. 그것이 당신이 원하는 것이라면. 그러나 그것은 TDD가 의도 한 것이 아닙니다. 이것이 결여되는 것은 확실히 TDD의 잘못이 아닙니다.

TDD는 디자인에 관한 것이 아닙니다. TDD를 사용하도록 설계를 변경해야하는 경우 테스트보다 더 큰 문제가 있습니다.


나는 TDD가 디자인이라고 말한 적이 없지만 디자인에 관한 것 입니다.
Mik378

1
밥 아저씨가 디자인하라고 했어요 그는 "당신이 나머지를 걱정하는 테스트 작업이라면 이봐"라고 말하지 않았습니다.
candied_orange 23시 41 분

1
내가 이미 말했듯이, 당신이 대화 할 수있는 사람의 규칙을 따르십시오. 클린 아키텍쳐는 BDUF 토론에 관한 것이 아닙니다. 어떤 부분에 있는지 확인하고 누구와 어떻게 의사 소통해야하는지 생각하십시오. 생각보다 민첩합니다. 그런 다음 TDD에서 테스트 할 수 있는지 묻습니다. 그렇지 않다면 당신이 잘못한 것입니다. 그렇다면 좋은 디자인은 단순한 테스트가 가능하기 때문에주의를 기울이기를 바랍니다.
candied_orange

6
어 ... 난 정말 "Test Driven Design"오명을 참을 수 없어. 테스트 작성 여부에 관계없이 키보드에서 행복하게 시작하기 전에 약간의 디자인을해야합니다.
RubberDuck은

1
이 정확한 지점에서 Bob 아저씨를 인용하려면 "기간을 디자인해야합니다" . 거기를 클릭하고 너무 성급하면 단어를 찾기 위해 모든 것을 읽으십시오. Martin은 TDD가 마법의 총알이 아니며 매우 취약한 코드 기반에서 살고 싶지 않다면 코드뿐만 아니라 테스트도 디자인해야한다는 사실을 강력하게 알고 있습니다.
candied_orange 10

4

TDD는 코드에 개발과 병행하여 필요한 모든 테스트 사례가 작성되도록합니다. 이것은 높은 수준의 디자인에는 영향을 미치지 않습니다. 참호 작업에서 더 많이 생각해보십시오.

DDD는 고급 디자인, 도메인 전문가와 엔지니어 간의 언어, 컨텍스트 매핑 등에 관한 것입니다. 응용 프로그램 고급 디자인의 동인이되어야합니다.

이것들은 두 가지 강력한 프로그래밍 방법론에 대한 얕은 설명입니다. 그러나 하루가 끝날 무렵 그들은 두 가지 매우 다른 일을 실제로 달성합니다.

DDD 언어 및 컨텍스트 맵핑으로 시작한 다음 결국 코드를 ​​작성할 때 TDD 연습을 시작하십시오. 그러나 TDD의 실행은 높은 수준의 디자인에는 영향을 미치지 않지만 테스트 할 수 있도록해야합니다. 여기에 약간의 경고가 있습니다.

참고해야 할 것이 있습니다. 응용 프로그램이 충분히 복잡한 경우에만 DDD를 연습해야합니다.


1
TDD는 테스트에 관한 것이 아니라 디자인에 관한 것입니다.
Mik378

나는 Uncle Bob이 설명한 것처럼 TDD의 세 가지 규칙을 기반으로합니다.
매트 오악 사카

GOOS 서적의 저자 인 스티브 프리먼 (Steve Freeman)은 다음과 같이 언급했다. TDD주기를 시작하기 전에 계층이나 인프라를 지정하지 않아야한다.
Mik378

나는 그 책에 익숙하지 않지만 동의하지 않아야합니다. TDD가 DI 및 클래스 그래프를 형성하는 것을 원하지 않습니다.
매트 오악 사카

3
@ Mik378 : TDD는 테스트에 관한 것이 아니라 주로 디자인에 관한 것이 아닙니다. TDD에 의해 유도 된 유일한 디자인은 단위 테스트를위한 디자인입니다. 디자인의 다른 모든 부분은 다른 곳에서 와야합니다. TDD를 구현 기술로 더 많이 본다.
Doc Brown

3

DDD 는 소프트웨어 디자인에 관한 것입니다.
TDD 는 코드 디자인에 관한 것입니다.

DDD에서 "모델"은 도메인 전문가의 모든 지식인 도메인의 추상화를 나타냅니다.

코드 초기 소프트웨어 디자인 모델에 TDD를 사용할 수 있습니다. 도메인에는 비즈니스 규칙과 도메인 모델이 있으며 테스트로 작성된 (첫 번째) 녹색이어야합니다.

실제로 도메인 기반 모델을 설계 한 후 테스트를 코딩 할 수 있습니다.
이 책은 "테스트를 통해 성장하는 객체 지향 소프트웨어" 링크 구매 구매 골격 , 육각형 아키텍처 및 TDD
와 함께이 방법을 사용하십시오 .

출처 : DDD 빨리-InfoQ


1
나에게도 소프트웨어와 코드는 동일하다
Konrad

1
또한 동일 할 수 있습니다. 나는 말을하려고 : 소프트웨어 는 "솔루션", "시스템", "높은 수준의"와 같은 코드 는 "구현"으로, "낮은 수준", "세부 사항".
JonyLoscal

중요한 것은 "먼저 테스트하지만 테스트를 시작할 최소한의 골격이 필요하다는 것"이라고 생각합니다. 당신 은요?
JonyLoscal

1

테스트에서 디자인이 엄격하게 나오도록해야합니까?

아니요. (도메인 기반) 정의에 따른 디자인은 도메인 요구 사항에서 나와야합니다. 테스트 스위트, 데이터베이스 스키마 또는 ... (계속)인지 여부에 관계없이 디자인을 주도 할 수있는 것은 좋지 않습니다.

또는 빈 레이어 (응용 프로그램, 엔터티 / 도메인 서비스, 인프라)를 만들고 TDD가 각 레이어에 독립적으로 맞도록해야

(계속) ... 아주 성숙하고 인기있는 언어 인 경우에도 좋아하는 OO 언어로 된 클래스 / 클래스 계층의 정식 계층 (일부 "수백만 개의 파리가 잘못 될 수 없음")? .

DDD와 관련하여 OOP는 사람이 읽을 수있는 형태, 즉 프로그래머가 아닌 사람에게는 다소 명확한 요구 사항을 표현하기에는 부족합니다. 엄격한 유형의 FP 언어가 더 잘 작동합니다. Scott Wlaschin의 기능 프로그래밍 "도메인 모델링 기능"을 사용하여 DDD에 대한 책을 읽는 것이 좋습니다.

https://pragprog.com/book/swdddf/domain-modeling-made-functional

FP 언어를 사용하지 않아도 일부 를 빌릴 수 있습니다 (모든 이들의 불행하게도) 거기에서 아이디어를하지만, 실제로 그것을 읽는다면 그때는 아마 기능적인 언어를 사용하는 것이 좋습니다.

또한 TDD가 DDD 그림에 어떻게 맞는지에 대한 귀하의 질문에 답변합니다. 요컨대, 요구 사항이 기능적 스타일로 코딩되면 대부분의 유효하지 않은 상태와 시나리오를 표현할 수 없거나 컴파일 할 수 없으므로 엄청난 양의 단위 테스트가 필요하지 않습니다. 물론 FP 프로젝트에는 자동화 된 테스트를위한 장소가 있지만 테스트로 인해 주요 디자인 결정이 내려지는 것은 아닙니다.

완전한 원을 만들기 위해 "엄격한 TDD와 DDD를 결합하는 방법"과 같은 제목 문제로 돌아가 봅시다. 답은 간단합니다. 이해의 상충을 결합하거나 결합 할 필요가 없습니다. 요구 사항에 따라 디자인하고 디자인에 따라 개발하십시오 (TDD를 실제로하고 싶다면 먼저 테스트를 작성하여)


FP DDD 서적 및 전체 설명은 +1입니다.
Roman Susi
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.