개인 공부 (23.07~

[ DDD & SQL 중심 설계(SQL-DD) ] 정의와 비교

Song쏭 2023. 8. 9. 23:58

[Index]

✔️ DDD / SQL-DD 간단한 개념 ( 둘 중 하나를 골라쓴다는 개념이 아니다.) 및 차이점

✔️ DDD 개념 & 예시

✔️ SQL-DD 개념 & 예시

✔️ 실제 프로젝트에서 어떻게 사용할 지 예시

 

 

✔️ DDD / SQL-DD 간단한 개념 및 차이점

DDD는 비즈니스 로직과 도메인의 복잡성을 해결하기 위한 설계 방법론이다.

SQL-DD는 효과적으로 데이터베이스에 저장하고 관리하는 역할을 한다. (데이터베이스의 구조와 데이터 관리를 위한 설계)

 

두 설계 방식은 서로 다른 영역에 중점을 둔다. 

 

따라서, 실제 프로젝트에서는

도메인의 복잡성과 데이터의 일관성을 모두 고려해야 하므로,

DDD와 SQL-DD를 혼합하여 사용할 수 있다.

 

시스템의 유연성과 확장성, 유지보수성을 향상시키는데 기여하며

하나의 전체 시스템을 구성할 수 있다.

 

구분 DDD (Domain-Driven Design) SQL-DD (Data-Driven-Design)
접근 방식 비즈니스 로직과 도메인 중심 데이터와 데이터베이스 구조 중섬
목적 비즈니스 요구사항을 이해하고 모델링하는 데 집중 데이터 저장, 검색, 관리에 집중
주요 구성요소 엔터티, 값 객체, 집합체, 레포지토리 등 테이블, 뷰, 쿼리, 저장 프로시저 등
사용 단계 요구사항 분석과 설계 초기 단계 데이터베이스 설계와 구현 단계
장점 비즈니스 로직의 복잡성 관리, 유연성 및 확장성 제공 데이터의 일관성 유지, 효율적인 데이터 관리
코드 작성 비즈니스 로직과 관련된 도메인 개념 중심으로 작성 데이터베이스 테이블과 연동된 코드를 작성
유용도 복잡한 비즈니스 로직 다룰 때 데이터 중심의 간단한 CRUD 작업 때

 

✔️ DDD 개념 & 예시

Domain-Driven Design

 

1) 도메인이란? 

사전적으로는 (지식·활동의) 영역[분야], (책임의) 범위.

DDD에서 말하는 도메인은 비즈니스 도메인.

(비즈니스 도메인은 유사한 업무의 집합.)

 

2) DDD(Domain-Driven Design)란?

도메인 주도 설계

비즈니스 도메인 별로 나누어 설계 및 개발하는 방식.

복잡한 소프트웨어를 구축하면서 핵심 도메인의 복잡성을 관리하기 위한 설계 방법론.

쉽게 말하자면, 비즈니스 로직과 관련된 중요한 개념을 코드 안에서 명확하게 표현하고자 하는 설계 방식.

(핵심목표 : 모듈간의 의존성 최소화, 응집성 최대화)

 

++ 진짜 간단한 예시를 들자면

가격 계산 로직이 있다. 

보통 서비스에서 구현을 한다.

 

만약 로직에 쿠폰적용 로직도 생긴다면!

쿠폰 적용 로직은 서비스 로직에서 구현하는 것이 아닌!

 

Coupon 이라는 클래스를 생성하여,

그 클래스에서 쿠폰 적용 로직을 돌린다.

이런 의미가 DDD인 것이다!!

 

 

3) DDD 설계는 2가지로 나눌 수 있다.

DDD는

Strategic Design(개념 설계)와 Tactical Design (구체적 설계)로 나눌 수 있다.

 

Strategic Design(개념 설계) : 비즈니스 상황(Context: 대상 사용자, 상황)에 맞게 설계하자는 컨셉.

( ex) 선물 구매라는 도메인을 설계할 때, 대상이 부모, 자식, 친구인지에 따라 달라져야한다. )

이 단계는 문제 도메인을 이해하고 도메인의 주요 개념과 그 관계를 식별하는 데 중점을 둔다.

바운디드 컨텍스트, 엔터티, 값 객체 등의 핵심 도메인 개념을 식별하고,

이를 어떻게 조직할 지에 대한 고차원의 설계가 이루어진다.

이 단계에서는 도메인 전문가와 긴밀하게 협력하여 비즈니스 요구사항을 파악하고,

도메인 모델을 만든다.

 

Tactical Design (구체적 설계) : 개발을 위한 구체적인 설계도.

이 단계에서는 개념 설계에서 도출된 도메인 모델을 바탕으로

구체적인 코드 수준의 설계가 이루어진다.

엔터티, 값 객체, 레포지토리, 서비스 등의 실제 구현을 진행하며,

특정 기술 스택과 프레임워크에 맞게 설계를 상세화한다.

테스트 주도 개발(TDD)같은 방법을 사용할 수 있으며, 

애플리케이션 아키텍처와 통합 방식에 대한 결정이 이루어진다.

 

DDD 안에서 두가지로 나뉘는 설계를 정리하자면

개념 설계는 비즈니스의 핵심 개념과 그 관계를 이해하고 모델링하는 단계로, 고수준의 비즈니스 모델링에 중점을 둔다.

반면, 구체적 설계는 이러한 개념들을 실제 코드로 변환하며 세부적인 기술 사항을 결정하는 단계이다.

 

4) DDD의 핵심 개념

도메인 Domain : 문제 영역 또는 시스템이 해결하려는 비즈니스의 핵심 영역.

엔터티 Entity : 도메인 내에서 고유한 식별자를 가지고 있는 객체.

값 객체 Value Object : 속성 값을 가지나, 고유한 식별자를 갖지 않는 객체. 

집합체 Aggregate : 엔터티와 값 객체의 그룹. 특정 엔터티가 루트 역할을 하며, 일관성을 유지한다.

바운디드 컨텍스트 Bounded-Context : 특정 도메인의 한계를 정의. 같은 용어도 컨텍스트에 따라 다르게 해석될 수 있으므로, 명확한 경계를 설정한다.

레퍼지토리 Repository : 엔터티의 저장소를 추상화한다. 데이터베이스와 도메인 로직을 분리해준다.

팩토리 Factory : 복잡한 객체 생성 로직을 캡슐화한다.

서비스 Service : 도메인 내에서 수행되는 특정 비즈니스 로직을 수행한다.

 

5) DDD의 장점 및 단점

도메인 중심 설계 : 비즈니스 로직과 관련된 코드를 중심으로 구조화하기 때문에 도메인 전문가와 개발자 간의 소통이 원활해진다.

유지보수성 : 도메인 로직이 중심에 있으므로, 변경이나 확장이 수월하다.

 

이렇게 DDD는 복잡한 비즈니스 로직을 구조화하는 데 도움이 되지만,

도입과 구현이 복잡할 수 있으므로 프로젝트의 성격과 규모에 따라 적절히 고려해야한다.

 

✔️ SQL 중심 설계 개념 & 예시

1) SQL이란?

Structured Query Language

구조적 질의 언어.

관계형 데이터베이스 시스템(RDBMS)에서 자료를 관리 및 처리하기 위해 설계된 언어이다.

 

 

2) SQL 중심 설계란?

SQL-DD : Data-Driven Design

데이터베이스의 구조와 데이터 흐름을 중심에 놓고 설계하는 패턴이다.

데이터 핑퐁만 있는 작은 서비스 기반으로 하는 것.

데이터를 효율적으로 저장, 검색, 업데이트하기 위한 데이터베이스의 구조와 관계를 정의한다.

 

데이터베이스의 설계를 중심으로 개발을 진행핸다.

그러나, DDD로 정의된 도메인 모델을 기반으로 데이터베이스 스키마를 설계할 수도 있다.

 

SQL-DD는 DB의 변경사항이 개발 프로세스에 영향을 주기 쉽다는 것이 큰 단점이다.

 

객체지향 프로그래밍에서는 주로 캡슐화, 상속화, 추상화, 다형성 등을 통해 복잡한 현실 세계에 맞추어

현실 세계를 그대로 표현하는 것이 주 목표이다.

하지만, RDBMS는 데이터를 중심으로 잘 정규화하여 저장하는 것에 의미를 둔다.

따라서 객체지향과 RDBMS는 지향하는 바가 다르다.

 

cf) 현시대에서는 대부분 객체를 RDBM에 저장하고 있는 것이 현실이다.

객체지향과 관계형 데이터베이스 간의 패러다임 불일치를 해결하고 

SQL-DD에서 벗어나 Object중심으로 개발하기 위해 ORM(Object Relational Mappling)이라는 기술이 등장했다.

그리고 자바 진영에서는 JPA라는 ORM기술 표준이 존재한다.

(ORM : Object Relational Mapping 객체-관계-매핑의 약자. 객체와 데이터베이스의 관계를 매핑해주는 도구. ex)JPA)

내가 유일하게 해본 MyBatis는 ORM은 아니다.  SQL mapper 방식이다. Object와 SQL의 필드를 매핑하여 데이터를 객체화 하는 기술이다.

✔️ 실제 프로젝트에서 어떻게 사용할 지 예시

DDD예시

도메인 중심 설계에서는 비즈니스 로직을 중심으로 코드를 작성한다.

비즈니스 로직이 도메인 클래스에 포함되어 있으며, 서비스 클래스를 통해 복잡한 연산을 수행한다.

// 도메인 클래스
class Book {
    private String title;
    private Author author;
    private double price;

    // 로직
    public void applyDiscount(double discount) {
        this.price = this.price - discount;
    }
}

class Order {
    private List<Book> books;

    // 로직
    public double calculateTotal() {
        return books.stream().mapToDouble(Book::getPrice).sum();
    }
}

// 서비스 클래스
class BookService {
    public Book findBookByTitle(String title) {
        // DB에서 검색 등 로직
    }
}

// 사용 예
Book book = bookService.findBookByTitle("제목");
book.applyDiscount(10.0);

 

SQL-DD 예시

데이터 중심 설계에서는 데이터베이스 테이블과 직접적으로 매핑되는 객체와 SQL 쿼리를 중심으로 코드를 작성한다.

데이터베이스와 직접 매핑되는 DTO와 DAO를 사용하여 데이터의 검색과 변환에 중점을 둔다.

// DTO 클래스
class BookDTO {
    private String title;
    private String author;
    private double price;
}

class OrderDTO {
    private List<BookDTO> books;
}

// DAO 클래스
class BookDAO {
    public BookDTO findBookByTitle(String title) {
        String sql = "SELECT * FROM books WHERE title = ?";
        // DB에서 검색 후 BookDTO 반환
    }
}

// 사용 예
BookDAO bookDAO = new BookDAO();
BookDTO bookDTO = bookDAO.findBookByTitle("제목");

 

이렇게 공부를 해보니, 내가 프로젝트 진행을 할 시에는 아마 두가지 설계를 모두 사용하게 되지 않을까? 싶다!

 

데이터에 연결도 해야하고, 필요한 로직도 짜야하니... 두가지 기법을 사용해야하는게 아닌가? 

내가 이런식으로 MyBatis를 사용하여 해보았던 것 같은데..

(DTO설정하고 ModelDto라고 DB에서 일하는 친구를 하나 만들어서 활용하곤 했다... 나머지 로직에서 활동하는 친구들은 보통 RequestDto, ResponseDto를 사용했다.)

JPA를 사용하게 되면 달라지는 것일까? 자세히는 프로젝트를 더 진행해야지 감이 잡힐 듯 싶다.

예시를 더 찾아보고 익혀야겠다.

 

 

 

 

 

* 언그래머와 함께 공부하며 기록합니다.