brunch

You can make anything
by writing

C.S.Lewis

by 에디의 기술블로그 Jun 27. 2021

[스터디] 도메인 주도 설계 4주차
(1부 끝)

리포지토리


해당 글은 작년 스터디 중 작성한 글입니다. 잘못된 내용이 있어서 잠시 취소 처리하였습니다. 조만간 새로운 글을 작성해서 발행하겠습ㄴ다.



목차

1부. DDD 가볍게 시작해보기(경량 DDD)

[1주차] 1. 도메인 주도 설계
[1주차] 2. 전략적 설계

[1주차] 3. 전술적 설계

[2주차] 4. 값객체

[2주차] 5. 엔티티

[2주차] 6. 애그리거트

[3주차] 7. 도메인 서비스

[3주차] 8. 애플리케이션 서비스

[3주차] 9. 테스트 코드 작성하기

[4주차] 10. 리포지토리

[4주차] 11. 리포지토리 구현


[미정] 2부. DDD 깊게 알아보기

[5주차] 12. 바운디드 컨텍스트, 컨텍스트 매핑

[5주차] 13. 보편언어 정의하기

[5주차] 14. 이벤트 스토밍

[5주차] 15. 아키텍처

[5주차] 16. 의존성

[5주차] 17. 팩토리

[6주차] 18. 도메인 이벤트

[6주차] 19. 데이터 무결성

[8주차] 20. 실무 사례 검토


4주차 글을 읽기 전에


도메인 주도 설계 기본 지식 이해

혹시, 도메인 주도 설계에 대해서 전혀 모르는 개발자는 필자의 이전 글을 먼저 읽어보고 오길 바란다.

https://brunch.co.kr/@springboot/605

https://brunch.co.kr/@springboot/607

https://brunch.co.kr/@springboot/614

필자의 글이 너무 지루해서 읽기 싫다면, 에릭 에반스의 책을 읽으면 된다.

http://www.yes24.com/Product/Goods/5312881?OzSrank=2

해당 서적이 정말 좋은 책이지만, 아쉽게도 쉽게 이해가 되지 않을 것이다. 도메인 주도 설계는 은근히 어렵다. 책 한권으로 이해할 수 있는 개념이 아니다.


그래도, 반복해서 읽어보자. 언젠가는 깨닫게 되겠지...


경량 DDD

필자의 스터디는 경량 DDD 에 머물러 있다. 도메인 주도 설계는 크게 전략적 설계 와 전술적 설계로 구분된다. 필자의 글은 전술적 설계 위주로 설명하며, 전술적 설계의 일부 패턴을 적용하는 방법을 경량 DDD 라고 표현한다. 경량 DDD 는 도메인 주도 설계의 일부분에 해당하며 도메인 주도 설계의 전부가 아니다. 도메인 주도 설계의 전략적 설계에 대해서 스터디를 하지 못하는 것에 대해서 매우 안타깝게 생각한다. 솔직히 전략적 설계를 어떻게 스터디해야할 지 잘 모르겠다. 아쉽지만, 이번 스터디는 경량DDD 에 머물러 있고, 이 글을 마지막으로 마무리할 예정이다. 필자가 더 많은 경험을 쌓은 이후에 전략적 설계를 포함해서, 도메인 주도 설계의 진정한 가치에 대해서 깊게 고민하도록 하겠다.


JPA 에 대한 고민

도메인 주도 설계의 가치에 의하면, 데이터베이스 구현체는 중요하지 않다. (물론, 그럼에도 불구하고 주니어 개발자에게 데이터베이스 구현체를 빼놓고 설계를 하는건 쉽지 않은 일이다.) 어쨋든, 필자의 초기 계획에서는 JPA 를 같이 공부하는 방향이었으나, 결국 JPA 에 대한 상세한 스터디는 하지 않기로 했다. JPA 에 대해서 궁금한 개발자는 김영한님의 강의를 수강하거나, 최범균 님의 ddd start 를 정독하길 바란다.


도메인 주도 설계의 목표는

기술보다는 도메인에 대한 모델에 집중해 더 나은 소프트웨어를 만들어내는 것이다. - 에릭 에반스


10. 리포지토리


10.1 리포지토리

일반적으로, 소프트웨어 개발에서 리포지토리는 데이터 저장소를 뜻한다. 도메인 주도 설계에서 리포지토리도메인 객체를 저장하고 조회하는 책임을 수행한다. 보통 우리는 데이터 저장소를 떠올리면 관계형 데이터베이스(RDBMS) 를 먼저 떠올리게 되지만, 굳이 RDBMS 일 필요는 없다. NoSQL이 될수도 있으며, Document DB 인 몽고DB 가 될수도 있고, Key-Value 저장소로 많이 사용하는 레디스가 될수도 있다. 도메인 주도 설계의 가치에 의하면, 어떤 저장소를 사용하는지는 크게 중요하지 않다.


[필자의 지극히 개인적인 생각] 회사 상황에 의해서 도메인 주도 설계 가치를 완벽하게 맞추기 어려울 수도 있다. 필자가 근무했던 회사에서는 프로젝트 초기에 데이터베이스를 선택해서 품의를 올려야 한다.

또다른 이유로, 일부 주니어 개발자는 도메인 지식 보다는 기술에 대해서 더 많은 관심을 갖는다. 도메인 주도 설계는 기술에 집중하기 전에 도메인 지식에 집중하는 것을 중요한 가치로 생각한다. 하지만, 개발자의 호기심과 기술적 성장 욕심을 무조건 제한하는 것도 사실 그렇게 좋은 방향은 아니다. 적절하게 균형을 갖도록 해야한다. 기술과 도메인 지식 어떤 한 방향에도 치우치지 않고, 적절하게 균형을 유지하는 것을 선호하는 편이다.


도메인 주도 설계의 가치를 지키는 것이 아직은 쉽지 않지만, 가능하다면 데이터베이스에 대한 선택을 최대한 미루고, 도메인 지식에 집중하도록 습관을 갖도록 하자. 주니어 개발자들에게 소프트웨어 개발의 진정한 가치에 대해서 어떻게 설득시키면 좋을까? 고민이 된다.



도메인 주도 설계에서의 리포지토리는 데이터 스토어에 대한 명령을 추상화함으로써 데이터스토어를 직접 다루는 코드에서 해방될 수 있다. 단, 리포지토리의 책임은 객체의 퍼시스턴시까지다. 도메인 규칙은 리포지토리의 책임이 아니다. [2] 즉, 도메인 지식이 리포지토리에 스며들지 않도록 주의해야 한다.


[인용 - 에릭에반스's 도메인 주도 설계, 154페이지] 클라이언트는 이미 존재하는 도메인 객체의 참조를 획득하는 실용적인 수단을 필요로 한다. 인프라스트럭처에서 도메인 객체의 참조를 쉽게 획득할 수 있게 해준다면 클라이언트 측을 개발하는 개발자들이 좀 더 탐색 가능한 연관관계를 추가해 모델을 엉망으로 만들어 버릴지도 모른다. 애그리거트 루트에서부터 순회하지 않고 데이터베이스에 직접 질의해서 특정한 객체를 가져오는 잘못된 방식을 사용하게 될 것이다. 도메인 로직은 질의와 클라이언트 코드로 스며들어가서, 엔티티와 값객체 등 도메인 객체는 데이터 컨테이너로 전락하게 된다. 대부분의 데이터 접근 인프라스트럭처를 적용하는 데 따르는 기술적 복잡성으로 클라이언트 코드는 점점 복잡해지고, 도메인 계층에 대한 개발자들의 이해 수준을 낮춰 모델을 도메인 계층과 동떨어진 것으로 만든다.



10.2 캡슐화 & 의존성

리포지토리는 데이터베이스 접근 기술과 전략을 캡슐화한다. 무슨 말인지 잘 이해가 안될 것이다. 필자가 그린 허접한 그림으로 이해해보자.

리포지토리의 상세 구현체(저장소)는 무엇이 되어도 상관없다. RDBMS(MySQL, AWS RDS 등)이 되던, NoSQL(MongoDB, Redis 등)이 되던 상관없이, 리포지토리에서 응답하는 도메인 객체는 동일해야 한다. 심지어는, 데이터베이스 컬럼 이름을 변경해도 도메인 객체는 영향을 주어서는 안된다. 리포지토리는 데이터베이스 접근 기술과 전략을 캡슐화해야 한다. 이런 가치를 구현하기 위해서, 인터페이스를 정의하는 패턴을 사용하자. 아래 그림과 같이, 리포지토리를 인터페이스로 정의하였고, 클라이언트에서는 리포지토리 인터페이스를 사용한다.

조금 더 쉽게 이해를 하기 위해서, 아키텍처를 원으로 생각해보자. 도메인서비스 및 애플리케이션 서비스에서는 리포지토리 인터페이스를 호출한다.

아래 그림과 같이, 상세 구현체를 직접 참조하면 안된다.

클라이언트 코드는 리포지토리 구현을 무시한다. 단, 오해하지 말자. 코드가 무시한다는 얘기이며, 개발자도 구현을 무시할 필요는 없다. 개발자는 어떤 상세 구현체인지 알고는 있어야 한다. 해당 내용은 에릭 에반스의 책에 같은 내용이 있으니 읽어보길 바란다. 물론, 도메인 주도 설계 가치에 맞게 설계&개발을 하게 되면 상세 구현체에 대한 선택을 최대한 미룰 수 있다. 추후에 구현체(저장소)를 변경하는 것도 어렵지 않게 가능할 것이다.


10.3 리포지토리와 애그리거트

일반적으로 애그리거트 와 리포지토리 사이에는 일대일 관계가 된다.


매우 중요한 내용인데, 애그리거트에 대해서 따로 정리가 필요할 것 같다. 조만간 각잡고 정리해서 새로운 글로 작성하겠다.



10.4 도메인 로직이 스며들어가지 않도록

리포지토리에 정의되는 행위는 보통 도메인 객체를 저장하거나 조회하는 것이다. 그 외에는 굳이 필요하지 않다. 보통 리포지토리에는 아래와 같은 메서드를 정의한다.


- Optional<User> findById(id)

- List<User> findAll

- List<User> findByName(name)

- void save(entity)

- void saveAll(entity list)


지난 글에서, 도메인 로직이 애플리케이션 레이어에 스며들지 않도록 주의해야한다고 설명했었다. 리포지토리는 비록 도메인 서비스와 같은 도메인 모듈에 속하지만, 도메인 로직이 스며들어가지 않도록 주의해야 한다. 도메인 로직은, 우선 도메인 객체(엔티티, 값객체, 애그리거트)에 정의해야하며, 도메인 객체에 정의하기 애매한 경우에만 도메인 서비스를 사용하면 된다.


도메인 로직이 리포지토리 및 애플리케이션 레이어로 스며들어가지 않도록 주의하자.


10.5 패키지 구조

패키지 구조는 다음과 같다.

- application

- domain

- infrastructure

- interfaces

리포지토리는 도메인 패키지에 속하지만, 리포지토리의 상세 구현체는 인프라스트럭처 패키지에 위치하게 된다.

상세한 내용은 11장에서 설명하겠다.


11. 리포지토리 구현


지겹게 얘기하고 있지만, 도메인 주도 설계의 가치에 의하면 리포지토리 구현체는 중요하지 않다. 리포지토리 구현체에 영향을 받지 않고... 구현 기술에 의존하지 않고 도메인 모델을 설계하는것이 중요한 가치이고 목적이기 때문이다. 하지만, 주니어 개발자는 리포지토리 구현체를 배제하고 설계할 실력이 안되는 경우가 많다. 즉, 주니어 개발자들은 도메인 주도 설계 가치를 완벽하게 따르면서 설계하는 것이 쉽지 않을수도 있다.


[지극히 개인적인 생각] 이론에 치우치지도 말고, 기술에 치우치지도 않도록 하자. 아마도.. 필자의 생각에 대해서, 원칙주의자 개발자 분들께서 엄청나게 필자를 욕할 것 같다. 하지만, 현실 세계에서 많은 프로젝트를 경험해보니, 이론이 전부가 아니란 생각도 해본다. 하지만, 핑계인 것 같다. 필자의 역량 부족이며, 필자의 경험 부족이다. 많은 경험을 하게 되면, 그땐 조금 더 나은 방향으로 주니어 개발자들과 협업해서 좋은 소프트웨어를 만들어 갈 수 있지 않을까... 기대해본다.



11.1 JDBCTemplate

필자는 실무에서 JDBCTemplate를 사용하지 않지만, 도메인 주도 설계를 설명하기 위해서 잠시 다시 살펴보겠다. 아래와 같이 리포지토리 구현체를 인프라스트럭처 레이어에 구현하였다. 리포지토리 인터페이스에는 전혀 영향을 받지 않는다.  

구현 코드는 아래와 같이, JDBCTemplate 를 사용해서 데이터베이스에 연동해서, 데이터를 가져올 수 있다.

위에서로 서명했듯이, 리포지토리 인터페이스는 아래와 같이 전혀 변함이 없다.

클라이언트 코드에서 리포지토리를 호출하는 방법에는 영향을 받지 않는다는 뜻이다.

그래!! 클라이언트 코드는, 리포지토리 구현을 무시한다.

사실, 인터페이스의 구현체를 누군가는 주입해줘야 한다. 이 역할은 스프링 IoC 에서 주입해줄 것이다. 스프링 관련 내용은 이 글의 핵심 주제는 아니므로, 스프링 프레임워크를 상세하게 알고 싶은 개발자는 인프런의 김영한님 또는 백기선님 강의를 수강하길 바란다.


이때 중요한 사실은, 리포지토리는 도메인 객체(DDD의 엔티티)를 반환한다. (JPA 의 엔티티가 아니다. 헷깔리지 않도록 하자.)  JDBCTemplate를 사용해서 데이터베이스에서 조회한 데이터를 도메인 객체로 매핑해주는 과정이 필요하다. 필자는 아래와 같이 간단하게 매핑을 해주는 메서드를 작성하였다. 코드가 깔끔하진 않다. 코드는 대충 참고만 해주길 바란다.

지겹도록 얘기하고 있지만, 데이터베이스 컬럼이 변경되거나, 데이터베이스 자체가 변경이 되어도 도메인 객체와 리포지토리 인터페이스에는 전혀 영향을 주지 않는다. 인프라스트럭처 레이어에 위치한 구현체에서 적절하게 매핑해주면 된다. 간혹, 리포지토리 구현체는 조금 복잡해질수는 있다. 사실 조금 복잡해져도 상관없다. 리포지토리 인터페이스와 도메인 객체가 변함이 없도록 구현해주면 크게 상관없다. (물론, 구현체가 너무 심각하게 복잡해지면 운영에 문제가 될 것이지만...)


11.2 MyBatis

MyBatis 를 사용해도 JDBCTemplate 에서와 유사하게 구축할 수 있다. MyBatis 코드를 전부 인프라스트럭처 레이어에 위치한다. JDBCTempalte 대신 MyBatis 를 사용해도, 도메인 패키지의 도메인 객체(엔티티, 값객체, 애그리거트)와 리포지토리 인터페이스는 영향을 받지 않는다.

위 패키지와 같이 인프라스트럭처 레이어에 MyBatis 코드가 위치할 것이다. MyBatis에 대한 상세한 설명은 생략하겠다.



아... 이제 지겹다. 입이 아플 정도이지만, 또 얘기를 하면... JDBCTemplate 를 사용하든, myBatis 를 사용하던 리포지토리 및 도메인 객체에는 영향을 받지 않는다는 것이, 이 글의 핵심 가치이다. 그리고, 이 가치를 유지하기 위해서는 리포지토리 캡슐화 및 의존성이 중요하다.

이정도로 설명했는데도 이해가 잘 안된다면...

필자의 글을 이제 그만 읽고, 다른 참고자료를 읽어보는게 좋을 듯 하다. ㅠㅠ


글로 설명하는게 한계가 있다. 필자의 역량 부족이다.


11.3 JPA (엔티티 클래스 분리)

드디어... 논란의 대상인 JPA 에 대해서 알아보자. 도메인 주도 설계의 가치에 맞게, 도메인 객체에 영향을 주지 않도록 구현해보자.



일단 시작하기 전에,

도메인 주도 설계의 엔티티 와 JPA 엔티티는 근본적으로 같지 않다라는 개념을 먼저 이해하도록 하자.


도메인 객체 엔티티 != JPA 엔티티 (같지 않다.)


그럼에도 불구하고 대부분 프로젝트에서는 JPA 엔티티를 도메인 객체의 엔티티와 동일한 클래스로 사용한다. 여러분은 어떤 선택을 할 것인가?


1. DDD 엔티티, JPA 엔티티 를 같은 클래스로 사용한다.

2. DDD 엔티티, JPA 엔티티를 별도의 클래스로 분리해서 사용한다.

3. 이런 고민할바에는 차라리 JPA 를 사용하지 않겠다.


필자가 해당 질문을 커뮤니티에 올렸었는데, 수많은 댓글이 달렸는데 개발자마다 각자 다른 의견을 갖고 있었다.


사실, 정답은 없다고 생각하며,

프로젝트 상황 및 소프트웨어 복잡도, 개발자 역량 등 팀 상황에 맞게 잘 선택해야할 것이다.


도메인 주도 설계의 가치에 맞게, 2번 방법으로 고민해보자. 인프라스트럭처 레이어에 ConfirmedCasePersistenceEntity 라는 JPA 엔티티를 정의하였다.

신규로 생성한 JPA 엔티티는 아래와 같이 정의하였다.

위 코드는 도메인 객체 와 퍼시스턴스 객체를 별도로 분리한 것이다. 도메인 객체는 전혀 영향을 받지 않기 때문에, 도메인 객체는 그대로 유지된다.  

리포지토리 인터페이스를 구현한, 구현체를 작성해보자. 인터페이스에서 선언한 메서드를 모두 구현해야 한다. 우리는 JPA 를 사용하기 때문에 아래와 같이 엔티티매니저를 주입해서 사용할 것이다.


1) 리포지토리 인터페이스를 구현하는 구현체 클래스를 작성한다. 인프라스트럭처 레이어에 위치한다.

2) @PersistenceContext 어노테이션을 사용해서 엔티티매니저를 주입해준다.

3) 엔티티 매니저를 사용해서 데이터를 조회하고, 영속성 컨텍스트에서 관리하도록 한다.

4) JPA 영속성 컨텍스트의 객체를, 도메인 객체로 변환해준다.


JDBCTemplate 에서 구현한 것과 마찬가지로, DB에서 조회한 데이터를, 도메인 객체로 변환할 필요가 있다.  즉, JPA 엔티티(퍼시스턴스)를 도메인 객체인 엔티티로 변환해주는 것이다.


필자의 허접한, 대충 작성한 코드는 참고만 해주길 바란다.


도메인 객체로 변환해주는 과정이 조금 번거롭지만, 도메인 주도 설계 가치에 맞게 구현하였다. 유연한 구조이며 데이터베이스를 유연하게 변경할 수 있을 것이다. 심지어는, JPA가 아닌 다른 기술로 변경하는 것도 유연하게 가능할 것이다. 하지만, 위와 같은 방식이 언제나 옳은지에 대해서 확신이 없다. 오히려 소프트웨어를 더 복잡하게 만드는것이 아닌지? 유연하며, 확장성은 좋아졌지만, 초기 개발 생산성이 떨어지지 않나? 중복코드가 너무 많이 발생하지 않을까? 이럴거면 복잡한 JPA 를 굳이 사용할 필요가 있을까?


솔직히 아직은 잘 모르겠다.


11.4 Spring Data JPA (엔티티 클래스 분리)

Spring Data JPA 를 사용해도 내부 동작은 크게 다르지 않다. Spring Data JPA 는 결국 JPA를 쉽게 사용하기 위해서 제공해주는 라이브러리이다. JPA 내부 동작과 크게 다를게 없다. Spring Data JPA 를 사용하면 엔티티매니저를 직접 주입할 필요가 없다. 아래와 같이, JpaRepository 를 상속받으면 개발자가 구현체 코드를 작성하지 않아도, 자동으로 상세 구현체가 생성된다. 그리고, 생성된 구현체는 Bean 으로 등록이 되고, 스프링 IoC 컨테이너에서 관리하게 된다.

필요한 곳에서 주입해서 사용하면 되며, 개발자가 주입을 할 수 있게 선언해주면, 리포지토리 구현체에 대한 주입은 스프링 IoC 컨테이너가 알아서 친절하게 주입해줄 것이다.


자, 샘플 코드를 보자.

상세한 설명은 생략한다...


11.5 Spring Data JPA (엔티티를 같은 클래스로 매핑)

도메인 객체와 퍼시스턴스 객체를 같은 클래스로 매핑해보자. 위에서도 설명했지만, 도메인 주도 설계의 가치에는 맞지 않는다. 아래와 같이 도메인 객체인 ConfirmedCase 클래스에 @Entity 어노테이션을 선언해준다. 도메인 객체이면서 동시에 JPA 엔티티(퍼시스턴스 객체)가 된다.

값객체를 @Embedded 어노테이션을 선언해서 사용할 수 있다.


상세한 설명은 생략한다...



그리고, 리포지토리 인터페이스에 JPARepository 를 상속받도록 변경한다.

save, findById 와 같은 메서드는 JpaRepository 에서 기본으로 제공하는 메서드이기 때문에 주석처리를 하였다. 패키지 구조를 살펴보자. 인프라스트럭처 레이어에는 별도의 코드를 구현하지 않아도 된다.


인프라스트럭처에 리포지토리 구현체를 직접 작성할 필요가 없는 이유는, 스프링 프레임워크가 알아서 자동으로 구현체를 생성해주기 때문이다. SimpleJpaRepository 소스 코드를 찾아보자.

아키텍처 그림으로 보면 아래와 같다.

SimpleJpaRepository 는 개발자가 구현한 구현체가 아니라, 스프링이 제공해주는 것이다.


자... 아키텍처 전반에 JPA 의존성이 침투하였다.


도메인 주도 설계의 가치에는 맞지 않다.


다시 질문해보겠다. 여러분의 선택은 무엇인가?


1. DDD 엔티티, JPA 엔티티 를 같은 클래스로 사용한다.

2. DDD 엔티티, JPA 엔티티를 별도의 클래스로 분리해서 사용한다.

3. 이런 고민할바에는 차라리 JPA 를 사용하지 않겠다.


정답을 찾기 위해서, 필자가 스프링 커뮤니티에 질문을 올렸지만 결국 정답을 찾지 못하였다...



[지극히 개인적인 의견] JPA 를 유연하게 사용할 자신이 있다면, 같은 클래스로 사용해도 괜찮다는 의견이다. 반대로, JPA 를 유연하게 사용할 자신이 없다면, 차라리 DDD 프로젝트에서는 JPA 를 사용하지 않는게 좋을 것 같다. 일부 개발자들은 엔티티 클래스를 반드시 분리해야 한다는 의견이며, 도메인 객체에 @Entity 어노테이션을 갖다 붙이는 것에 대해서 매우 불편해할 것이다. 필자 역시 이상적으로는 매우 동의한다. 하지만, 현실에서 해당 가치를 지키는 것이 쉽지 않을 때가 있다. 유연성은 증가하겠지만, 중복코드가 발생하고 소프트웨어가 오히려 더 복잡해질수도 있다. 사실, 오랜 고민끝에 내린 필자의 결론은 JPA라는 기술 자체가 DDD 에 적합하지 않다고 생각한다. 그래서, DDD 를 하고 싶다면 JPA 를 사용하지 안했으면 좋겠지만, 회사 업무에서 대부분 JPA 를 사용하고 있는 상황이라서, JPA 를 사용하지 않도록 팀원들을 설득하는 일이 쉽지 않을 것이다. 그렇다면 DDD를 포기해야할까? 아직 정답을 모르겠지만, 필자가 경험이 부족하다는 사실을 심각하게 깨닫게 된다. 어쨋든, 비용의 문제라 생각하며, 어떤 선택을 하던, 소프트웨어가 복잡해지지 않도록 하는 것이 개발자의 책임이라는 사실을 언제나 명심해야할 것이다.




11.6 Spring Data JDBC

Spring Data JDBC 는 도메인 주도 설계를 위해서 시작된 프로젝트이다. 도메인 객체와 퍼시스턴스 객체를 같은 클래스로 사용할 수 있도록 제안한다.(필자의 추측이며, 개발자한테 직접 들은 얘기는 아니다.) 그럼에도 불구하고, 일부 개발자는 Spring Data JDBC 를 사용할 때도 별도의 클래스로 분리해야한다고 주장한다. 필자 역시 해당 의견에 일부 동의하지만, Spring Data JDBC 를 사용하는데 굳이 엔티티 클래스를 분리할 필요는 없다고 생각하며, Spring Data JDBC 의 목적과 맞지 않는다고 생각한다. Spring Data JDBC 를 왜 만들기 시작했는지 곰곰히 생각해볼 필요가 있다. Spring Data JDBC 에 대해서는, 나중에 시간을 내서 각잡고 글을 써보도록 하겠다.


11.7 NoSQL

상세한 소스 코드는 생략하겠다. 리포지토리 인터페이스와 도메인 객체는 영향을 받지 않도록 인프라스트럭처 레이어에 NoSQL 관련 코드를 작성하면 된다.


도메인 주도 설계에 의하면, 애그리거트의 크기를 최소화하게 되며, 애그리거트 사이의 참조를 식별자를 사용하게 된다. 그래서, 개인적인 생각으로는 도메인 주도 설계의 가치에 맞게 개발을 하게 되면, RDBMS 보다는 NoSQL 이 더 적합할 것 같다는 생각이다.


필자가 NoSQL 기반의 프로젝트 경험을 더 쌓은 이후에, 나중에 각잡고 글을 작성하겠다.


11.8 마무리

도메인 주도 설계를 스터디하면서, 리포지토리 구현체를 논하는게 무슨 의미가 있을까? 데이터베이스 기술과 전략은 옵션으로 최후에 선택해야 한다. 결국 중요한건 도메인 지식이며, 도메인 지식을 이해하기 위해서 도메인 전문가와 함께하는 전략적 설계 과정이 더 중요할 것이다.



(허접했던)도메인 주도 설계 스터디

1부를 마무리하면서


소프트웨어 개발의 궁극적인 목적

이번 스터디에서는 경량 DDD에 머물러 있지만, 나름 의미있는 시간이었다. 소프트웨어를 바라보는 관점이 바뀌었고, 복잡한 도메인을 어떻게하면 심플하게 구현할 수 있을지에 대해서 고민하게 되는 계기가 되었다. 도메인 지식을 이해하는 방법에 대해서 더 깊게 생각하게 되었고, 소프트웨어 개발의 궁극적인 목적에 대해서 생각할 수 있는 시간이었다. 만약, 도메인 주도 설계로 인해서, 오히려 소프트웨어가 더 복잡해진다면, 차라리 그럴바에는 도메인 주도 설계를 아예 하지 않는것이 좋을 것이다.



나에게 주어진 숙제

필자가 도메인 주도 설계에 대해서 검토하면서, 부족한 부분을 깨닫게 되었다. 도메인 주도 설계를 공부하다보니 자연스럽게 객체지향 프로그래밍에 대해서 고민하게 되었다. 조영호님의 "오브젝트" 를 정독 중인데, 이해가 쉽지 않았다. 그래서, 오브젝트를 이해하기 위해서, 해당 서적의 샘플 코드의 테스트 코드를 작성 중인데, 자연스럽게 테스트 주도 개발에 대해서 고민하기 시작하였다. 도메인 주도 설계 스터디를 하다가 객체지향 프로그래밍, 테스트 주도 개발... 나에게 갑자기 너무 많은 숙제가 생겼다. 다음 스터디는 아마도 아래 주제가 될 것이다.


- 도메인 주도 설계 2부

- 객체지향 프로그래밍

- 테스트 주도 개발


레퍼런스


[1] 도메인 주도 설계 핵심 (반 버논 지음, 에이콘 출판사)

[2] 도메인 주도 설계 철저 입문 (나루세 마사노부 지음, 위키북스)

[3] 도메인 주도 설계 - 소프트웨어의 복잡성을 다루는 지혜 (에릭 에반스 지음, 위키북스)

[4] DDD START! 도메인 주도 설계 구현과 핵심 개념 익히기 (최범균 지음, 지앤선)

브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari