본문 바로가기

Backend

DDD 레이어드 아키텍처에 대한 고민

반응형

 

모놀리식 아키텍처라고 하면 계층구조를 Controller - Service - Repository를 떠올려왔었다. 

백엔드에 발을 들이고 얼마동안은 인터페이스의 역할의 중요성도 모른채로 데이터가 요청이 들어오면 비지니스 로직을 거쳐 영속성 계층에서 데이터를 조회해 클라이언트에게 응답해주는 단순한 구조로만 여겼었다. 서비스의 목적은 클라이언트에게 올바른 결과값을 되돌려주는 점에서는 동의하지만, 개발 과정에서 고려했어야했을 포인트들을 놓친 채 시간을 보냈었던 점이 아쉬움이 남는다. 

 

API를 빠르게 만들고 정상 동작하는지 테스트만 진행하다보니 왜 이건 이렇게 작성해야하고, 이 방식이 왜 좋은지?에 대한 의문점을 가져오지 않았다. "만들면서 배우는 클린 아키텍처" 책을 읽으면서 내가 무심코 생각없이 만들었던 결과물들이 책에서 소개하는 배드케이스에 속하는 것을 알았다. 높은 의존성, 강한 결합도를 내재하고 있는 내 코드들이 떠올랐다.

 


고민1. 폴더 계층구조를 어떻게 만드는게 장기적으로 프로젝트가 더러워지지 않고 잘 유지될지 고민이다

 

요즘 새로운 프로젝트를 준비하면서 계층구조를 어떻게 구성해서 깔끔하고 클린한 코드들 작성할 수 있을지 고민을 하고 있다. 몇번 회의를 거쳐 폴더 구조는 다음과 같이 진행하기로 했다.  DDD와 계층형을 섞어서 하이브리드로 구성했다. 해당 계층구조로 개발 일정을 조율하면 서로 충돌이 일어나지 않고 코드 관리와 협업이 편리해질 수 있다고 생각했다.

 

도메인1 ( 상점 )

    ㄴ Presentation

    ㄴ Application

    ㄴ Domain

    ㄴ InfraStructure

도메인2 (투두리스트)

    ㄴ Presentation

    ㄴ Application

    ㄴ Domain

    ㄴ InfraStructure

 

장점을 먼저 떠올렸었다.  각 도메인이 독립적으로 구성되어있어서 도메인 간 경계가 명확해진다. 비지니스 로직의 응집도가 높아지고 도메인 간 독립성이 강해진다는 점이 돋보일 것 같다.

다만, 도메인 간 통합이 필요할 때 어떻게 작업을 해야할지? 추가적인 설계가 들어가면 이 레이어가 결국 무너지게 될지 걱정이 든다. 공통적으로 사용되는 유틸 클래스나 Config클래스들은 각자 따로 묶어야할 것이고, 프로젝트 구조가 복잡해질 것 같긴 하다.

 

Presentation

    ㄴ Controller

    ㄴ DTO

    ㄴ Assembler

Application

    ㄴ Service Interface

    ㄴ Service Impl

    ㄴ Facade Interface

    ㄴ Facade Impl

Domain

    ㄴ Repository Interface

    ㄴ Domain1 class 

    ㄴ Enum

InfraStructure

    ㄴ Repository Impl

    ㄴ Entity1 class

    ㄴ DTO

 

Util

    ㄴ aaUtil.class

Config

    ㄴ aaConfig.class


고민2.

JPA를 사용하기 때문에 영속모델(Entity 클래스)이 필요한데, 도메인 모델과 분리를 시킬지, 영속모델을 도메인 모델로 사용할지 고민이다.

 

이번 프로젝트는 의존성을 최소화시키고 컴포넌트간 결합도를 낮추는 것을 목표로 잡아보려고 한다. 영속모델과 도메인모델이 동일해지면 도메인계층과 영속 계층간 강한 결합이 일어나게 될 것이다. 책임이 분리가 안되고 영속모델이 DB 매핑도 하고 비지니스 로직까지 타야하기 때문이다. 도메인 계층에선 영속성 계층을 몰라도 개발할 수 있기 때문에 결합도가 떨어지게 되어 도메인 모델은 순수하게 관리할 수 있을 것이다. 

 

더 공부하다보니 엔티티 모델은 기본 생성자를 만드는 것을 강제하고 있는데 이게 도메인모델에는 포함해서는 안될 프레임워크에 특화된 결합의 예시라고 한다. 장단점과 프로젝트 목표를 생각했을 때, 영속모델과 도메인 모델은 분리하여 개발하겠다. 

 

다만, lazy loading이 영속모델과 도메인과 통합되어있을 때만큼 성능이 괜찮을지 의문이다. 

+ 변환 오버헤드가 너무 커질까봐 걱정도 있다. 도메인 모델로 변환할 때, lazy loading된 연관 엔티티에 접근하면 추가 쿼리가 발생하고, 불필요한 데어터까지 가져올 가능성이 있다. 

+ 영속성 컨텍스트와 도메인 모델 간의 불일치로 인해서 세션 관리가 어려워질 가능성이 있다. 지연로딩을 수행하려 할 때 영속성 컨텍스트가 닫힌상태일 때 해결책을 고민해봐야한다. 


고민3.

 

반응형