system architecture 에 관심이 생겨 찾아보던 중, software 를 설계하는데에는 여러 기법이 존재한다는 사실에 대하여 알게 되었다. 대표적으로 DDD, TDD, BDD 등이 있다. 순서대로 알아보고, 그 차이점에 대해서도 공부해보자.

What is DDD?
DDD patterns 이란 도메인 주도 디자인 Domain driven design 의 약자로, 소프트웨어의 복잡성을 관리하기 위해 business logic 을 domain 별로 나누어 설계하는 방식을 의미한다. 도메인 주도 설계 라고도 한다. Domain language 의 설립자인 에릭 에반스(Eric Evans) 가 서술한 동명의 저서에서 따온 system architecture 로, clean architecture 가 그랬듯, layered architecture 의 여러 방식 중 하나이기도 하다.
features of DDD
DDD 는 지금까지 없던 새로운 기법이 아닌 OOP 본래 모습을 되찾기 위한 system architecture 이다.
2002년 마틴 파울러는 그의 저서 PoEAA(Pattern of Enterprise Application Architecture) 를 통해 엔터프라이즈 어플리케이션에 있어서 OOP 가 가져야 할 모습에 대한 재발견을 이끌어 낸다. PoEAA 는 디자인 패턴을 단순히 확장한 개념이라기 보다는 OOP 본래의 패러다임에 충실하여 엔터프라이즈 어플리케이션의 각 요소들의 본질과 관계를 새롭게 패턴화하여 정의하고 있는데, DDD 는 바로 이 PoEAA 를 기반으로 하여 서술되었다. 즉 DDD 역시 OOP 의 개념에 충실한 디자인 패턴이라는 것이다.
도메인 주도 설계의 저자인 에릭 에반스는 분석, 모델링, 설계, 프로그래밍에 대한 과도한 분리는 모델 주도적인 설계를 방해한다고 서술했다. 그리하여 DDD 는 도메인의 모델과 logic 간 연결성의 느슨하고 높은 정도에 집중하여 프로그램을 설계한다. 또 분석 작업과 설계, 구현에 이르는 모든 문서와 코드를 동일한 언어를 사용하여 작성함으로써 기술 전문가와 도메인 전문가간의 협업을 보다 더 쉽게할 수 있도록 도와준다.
DDD pattern 에 따른 프로그래밍 설계 시에는 수직적으로 한번에 처리하는 방법 보다 agile process를 이용하는것이 좋다. 또, 모델링부터 구현에 이르는 많고 다양하게 얽힌 구성을 같은 언어로 유연하게 설계하고 분리해야 하므로, 단순한 CRUD application 보다는 복잡하고 대용량의 application 을 처리하는데에 유리하다.

structures


DDD 의 개요는 대략 이런 식의 레이어로 구성되어 있다. 복잡성에 따라 application layer 와 domain 을 한 계층으로 합칠때도 있다. clean architecture 와 유사하게, 상위계층에서 하위계층으로의 의존만 존재하고 하위계층은 상위 계층에 의존하지 않는다.

의존성 규칙의 방향이다.
때로는 application layer 가 infrastructure layer에 의존하게 되는 경우도 존재한다. 이러한 경우 test 및 기능의 확장이 어려워, 의존성 주입을 통해 해결하고는 한다. 의존성을 주입하면 하위의 모듈이 상위의 모듈에 의존하도록 변경할 수 있기 때문이다.

그럼 이제 각각의 레이어에 대해 간단하게 살펴보자.

Domain layer
도메인이란 소프트웨어로 해결하고자 하는 문제 영역을 의미한다. DDD 에서 말하는 도메인이란 비즈니스 domain 이다. 만들고자 하는 서비스를 잘게 쪼개놓은 단위라고 이해하면 편하다.
domain layer 의 구성 요소들
- ref : ABP FRAMEWORK DOCUMENTS
- Entity : 각각의 ID 를 가지는 models
- Values : ID 가 필요하지 않은 하위 models. 같은 property 안에 두 개의 value 가 들어있을 수 있고, 같은 object 로 고려될 수 있다.
- Aggregate & Aggregate Root : 연관된 entity 와 value 들의 집합. aggregate root 는 aggregate 들의 대표 entity 로, aggregate 를 관리한다. 내부 구현을 숨겨, aggregate 단위로 캡슐화 할 수 있도록 도와준다. 해당 개념에 대한 추가 공부 필요
- Repository (interface): 도메인과 애플리케이션을 database 에 접근할 수 있게 하고, 비즈니스 코드와 dbms 의 분리를 도와준다. 즉, 도메인 모델의 영속성을 처리한다.
- Domain Service: 여러 aggregate 나 entity 를 포괄하는 동작을 모델링한다.
- Specification: entity 와 business object 의 황장 및 재사용을 돕는다. 명세서라고도 한다.
- Domain Event: 변경이 있을때 시스템의 다른 부분에 이를 알릴 때 사용된다.
Applcation layer
소프트웨어가 수행할 작업을 정의하고 도메인 서비스를 호출하여 문제를 해결하도록 지시한다. 실제로 수행할 작업에 대한 정의만 이루어질 뿐, business logic 이나 domain 이 포함되어 있지 않다. 상호 작용에 필요한 작업들만 정의되어 있다.
Presentation layer
UI. client 의 요청을 application layer 에 전달하고, 응답을 내보내는 역할을 한다.
Infrastructure layer
실제 구현을 담당하는 계층으로, 도메인 entity 의 data 가 RDB, SQL 등의 database 혹은 기타 repository 에 저장되는 것을 의미한다.
What is TDD?
TDD pattern 이란 테스트 주도 개발 Test Driven Development 의 약자이다. TDD 는 매우 짧은 개발 서클의 반복으로 이루어지는 프로세스로, 새로운 기능에 대해 자동화된 test case 를 작성하고 해당 케이스를 통과하는 가장 좋은 코드를 작성하도록 하는 방법이다. 즉, test case 를 먼저 작성한 후에 개발이 이루어지는 것이다.

TDD pattern 을 이용할 경우 리팩토링이 빨라지고, 객체지향적이고 확장이 용이한 코드가 만들어질 확률이 높아 코드의 전반적인 퀄리티가 상승한다. TDD pattern 을 발견한 캔트 백(Kent Beck) 은, TDD 가 단순한 설계를 장려한다고 주장하기도 하였다.
다만 TDD 는 시간이 오래걸리고, test 때문에 코드를 바꾸게 되는 주객전도가 이루어질 수 있다. 무결성을 위해 모든 부분에 대한 test 가 이루어져야 하다보니 코드량이 방대해지고, 미처 catch 하지 못했던 error 가 발생할 수 있으며, 어떤 부분을 어떻게 test 해야할지 가늠하기가 어려울때도 있다. test code 를 퀄리티있게 만들기 위해서 요구되는 기초 지식이 높아 진입장벽이 있다는 것 또한 큰 단점이다.
What is BDD?
BDD pattern 이란 행동 주도 개발 Behavior Driven Development 의 약자로, TDD 에서 파생된 개발 프로세스이다.

TDD 가 test 중심적으로 개발하는 방면 BDD 는 business logic 에 집중하여 test case 를 개발한다. test case 를 성공시키기 위한 코드의 구현이 TDD 의 목적이라면, BDD 는 scenario test 를 통해 test case 가 필수 요구사항으로 여겨지도록 만든다는 차이가 있다. 좀 더 풀어서 설명하자면, 코드를 작성하기 전에 코드가 수행할 행위에 대한 명세를 먼저 작성하는 것이라고 말할 수 있겠다.
Scenario test
BDD 는 시나리오를 기반으로 test case 를 작성한다. 시나리오 테스트는 유효한 유저의 입장에서 진행되며, 하나의 시나리오 테스트는 given, when, then 의 구조로 이루어져 있다. given 은 시나리오 진행에 필요한 값을 설정하고, when 은 시나리오의 조건을 명시하며, then 은 시나리오를 완료하였을때 나오는 결과를 명시한다. test 대상은 given 에서 시작하여, when 을 만났을 때, then 의 상태로 완료되어야 한다.
예를 들어보자면 이런 방식이다.
// given
if a = 1 and b = 2
// when
result = a + b
// then
result = 3
better than TDD?
그렇다면 BDD 가 TDD 의 대체가 될 수 있을까? 요건들이 명확하게 주어지지 않는다면 scenario test 의 효과는 현저하게 떨어질 수 있고, TDD 와 마찬가지로 testing 을 위한 깊은 이해와 기술력이 요구되므로 BDD 또한 진입 장벽이 높은 기법이라 볼 수 있겠다.
difference
DDD pattern 이 business logic 이라는 커다란 그림을 그리기 위해 하나 하나의 작은 domain 을 나누는 것에서 개발을 시작한다면, TDD pattern 은 test code 의 작성에서부터 개발을 시작한다. 또 BDD pattern 은 어떤 방식으로 code 가 진행될 것인지를 염두에 두고 scenario code 를 작성한다. 즉, 세 기법 간의 가장 큰 차이는 어디에서 시작할 것인지에 대한 관점에 있다.

또 business logic 의 process 과정으로만 본다면 위의 그림처럼 DDD - BDD - TDD 순으로 정렬할 수 있다. BDD 가 DDD 와 TDD 의 중간 정도의 역할을 하는 것이다.
Conclusion
지금까지 DDD, TDD, BDD 라는 세 가지 software 설계 기법에 대하여 알아보았다. 사실 DDD 가 무엇인지 알기 위해 시작했던 공부였는데, J가 일하고 있는 곳이 BDD 기법을 사용한다고 하여 관련 검색어를 타고 타고 가다보니 여기까지 오게 되었다.
각각의 기법에 대하여 공부해보니 어떤 기법이 좋은지에 대한 정답은 딱히 정해져 있지 않은거 같다. 보다 중요한 것은 각각의 설계 기법을 이해하고, 자신과 팀이 처한 상황에 맞는 기법을 선택하여 실천하는 것이다. 그러기 위해서는 각각의 언어, frame work, logic 등에 대한 전반적인 이해도 필요하다.
해당 게시글의 가장 상단에 있는 세 기법의 교집합을 나타낸 다이어그램의 가장 중심이 되는 교집합 안에는 hybrid practice 라고 적혀있다. 기법을 선택하기 전에 문제를 완전하게 이해하고 해결하기 위한 시도가 가장 먼저 시작되어야 한다는 의미이다.
ref
https://www.moreagile.net/
https://ppiyo5.tistory.com/21
https://eocoding.tistory.com/36
https://beomseok95.tistory.com/293
https://phoenixnap.com/blog/tdd-vs-bdd
https://private-space.tistory.com/94
https://medium.datadriveninvestor.com/the-value-at-the-intersection-of-tdd-ddd-and-bdd-da58ea1f3ac8
https://habr.com/en/post/498926/
https://dev.to/thomasferro/summary-of-a-four-days-ddd-training-5a3c
https://docs.microsoft.com/ko-kr/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns/ddd-oriented-microservice
'basement' 카테고리의 다른 글
객체지향의 사실과 오해 (0) | 2021.10.06 |
---|---|
로드 밸런싱 (0) | 2021.05.07 |
tcp / udp (0) | 2021.05.03 |
clean architecture (0) | 2021.04.27 |
OOP (0) | 2021.04.27 |