[BE-STUDY] 도메인 주도 개발 필요할까?

soohee·2023년 4월 20일
1

BE-STUDY

목록 보기
5/7
post-thumbnail

DDD란?

DDD(Domain-Driven Design) 또는 도메인 주도 설계라고 부른다. 말 그대로 도메인 위주로 설계하는 기법이다. 한마디로, 새로운 개발 패러다임..?

DDD는 주로 어떨 때 사용하나?

주로 요구사항이 자주 변화해서 그 요구사항을 개발 언어로 변환하는 시간이 너무 많이 소요될 것 같을 때 쓰인다.

그러나 우리는 주로 데이터 중심 개발을 한다. 왜냐? 거의 동작이 CRUD 안에서 모두 충족이 되기 때문이다. 심지어, DDD관련 책의 저자는 단순 데이터 베이스 개발 도구를 사용해 솔루션을 만들 수 있다면, DDD에 시간과 돈을 낭비하지 말라고 전한다.

DDD는 그럼 데이터 중심 개발과 무엇이 다를까?

이것에 대해 생각해보기 위해 우리가 평소에 개발하는 방법인 데이터 중심개발은 어떻게 진행되는지를 먼저 생각해볼 필요가 있다.

  1. DB 설계를 통해 사용할 Domain을 정한다.
  2. 정한 Domain을 바탕으로 프로젝트 구조를 생성한다.
  3. Service에는 Domain에 대해 관련 CRUD로직을 만든다.
  4. Controller와 Service단에서 조합하여 API를 제공한다.

우리는 도메인을 정할 때, 주로 은행/계좌/사용자와 같이 명사로 나누는 경우가 많다. 그러나, DDD에서의 도메인은 조금 다르다. 사용자가 바라보는 관점에 따라 다양하고 변화할 수 있다. 예를들어, "B가 A의 계좌에 송금한다"와 같은 경우, "A/B/계좌"가 도메인이 될 수도 있고, "송금한다"가 도메인이 될 수도 있으며, 하물며 "A의 계좌에 송금한다"나 "B가 A의 계좌에 송금한다"와 같이 행위 전부가 도메인이 될 수도있다.
따라서, 도메인을 설계할 댸 사용자가 기능을 사용하기에 가장 효과적인 범위로 설정해야한다.

DDD는 어떤 방식으로 진행될까?

이벤트 스토밍 + 바운디드 컨텍스트 + 컨텍스트 맵의 단계를 거쳐 설계된다.
(해당 관련 자료는 더 공부한 다음 DDD에 대해서만 포스팅하도록 하겠다)

설계된 후 코드에서는 어떻게 작성될까?


총 4개의 계층으로 분리해서 작성된다.

Presentation

사용자의 요청을 해석하고 응답을 책임진다.

@RestController
public class MyController {

	private final CallService callService;
    
    @GetMapping("/callme")
    public Response callMeASAP(){
    	return Response.success(callService.call());
    }
}

우리가 지금까지 작성했던, 컨트롤러와 거의 흡사하다.

Application

비즈니스 로직이 작성되는 곳이다.

@Service
public class MyService {

	private final MyRepository myRepository;
    
    @Transactional(readonly = true)
    public Response exam(){
    	ExamDTO examDTO = myRepository.findExam();
        return new ResponseDTO(examDTO);
    }
}

여기서 중요한 점은, 데이터 변화를 할 때 그 로직은 도메인 계층으로 위임해야한다는 것이다.
서비스 단에서 exam.setStudentId(student.id); 와 같이 쓰이지 않고, 도메인단에서 쓰인다는 것이다.
이 Application계층에서는 트랜잭션 관리와 DTO변환 그리고 모듈간의 연계에 관한 로직이 들어간다.

Domain

비즈니스 규칙과 정보에 대한 실제 도메인 정보를 가지고있는 곳이다. 도메인의 변경부터 여러 로직이 구현될 수 있다.

@Entity
public class MySelf {
	private Long id;
    
    ... 대충 컬럼들 생략..
    
    public void stateChange(String name) {
    	if(String.isEmpty(name)){
        	throw new IllegalArgumentException("name 파라미터가 비어있다.");
        }
        this.name = name;
    }
}

Infra

도메인에서 봤을 때 외부 시스템을 호출하는 역할이다. JPA사용하는 것도 여기에 포함된다.

public interface MyRepository extends JpaRepository<User, Long> {

}

DDD를 공부해야겠다!

DDD는 역할분리와 책임분리로 인해 코드가 간결해지고, 또 각각 도메인들이 필요한 만큼 연결되기 때문에 자율성이 높아진다. 우리가 흔히 service로 모든 비즈니스 로직을 몰아버리는 것과는 다른 분리가 된다는 것이다. 과정이 보여지고, 그로 인한 동작이 명확해지기 때문에 정말 객체지향적인 방법이 아닌가 라는 생각이 든다.
여기서는 언급 못했지만, 아키텍처와 관련된 부분도 생각해서 짜야하는 것으로 알고있다. DDD를 공부하다 보면 여러 부분에서 인사이트를 얻을 수 있지 않을까라는 생각이 들어서.. 나중에 꼭 한번 써먹어보고 싶은 방법이라는 생각이 든다.

출처

https://incheol-jung.gitbook.io/docs/q-and-a/architecture/ddd
https://velog.io/@gowjr207/%EB%8F%84%EB%A9%94%EC%9D%B8-%EC%A3%BC%EB%8F%84-%EC%84%A4%EA%B3%84DDD%EB%A5%BC-%EC%84%A4%EB%AA%85%ED%95%B4%EB%B3%B4%EB%8B%A4

profile
🐻‍❄️

2개의 댓글

comment-user-thumbnail
2023년 4월 24일

저도 DDD에 대해 공부하면서 객체지향적으로 개발하기 위해 한번 사용해봐야겠다는 생각을 했어요!
DDD를 적용하기 위해 도메인 모델 패턴을 사용한다고 하니 관련 내용도 함께 살펴보시면 좋을거 같습니다
글 잘 읽었어용🐰

답글 달기
comment-user-thumbnail
2023년 4월 25일

행위를 도메인으로 설정한다는 포인트 덕분에 데이터 주도 개발과 다르다는 것을 확 느낄 수 있었습니다. 도메인 주도 개발은 난이도가 높다기 보다는 숙련도가 필요해 보이는 부분이네요. 대부분의 토이 프로젝트는 데이터 주도 개발로 진행이 가능하다 보니까 도메인 주도 개발을 접할 기회는 많지 않아서 아쉽습니다.. ㅠ

답글 달기