Giter Club home page Giter Club logo

ddd-start2's Introduction

도메인 주도 개발 시작하기

환경 설정

  1. docker run
 docker run --name mysql5.7.38 -e MYSQL_ROOT_PASSWORD=root -p 3308:3306 -d mysql:5.7.38 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
  • 현재 3306 포트 점유 중이므로, 3307 로 변경
  1. ddl.sql 실행
  2. init.sql 실행
  3. application 실행
    1. server.port : 8081 변경
    2. datasource의 url 변경

정리

annotation

  • @EmbeddedId
    • 참고
    • 복합키 사용을 위한 어노테이션
  • @Embedded
    • 참고1
    • 참고2
    • 클래스로 그 내용을 entity에 끼어넣기 위함.
    • Embed...들은 Entity의 가독성을 높히기 위함인듯 (복잡도를 낮추기 위함)
  • @Access
    • JPA가 엔티티 데이터에 접근하는 방식을 정의함.
    • 참고1
    • 참고2
  • AttributeConverter
  • @SecondaryTable

읽으면서..

1ch

  • 일반적인 애플리케이션의 구조는 [표현 - 응용 - 도메인 - 인프라스트럭처]
    • 표현은 UI
    • 응용은 서비스, 뭔가 조합해서 처리하는 거
    • 도메인은 말그대로 도메인. 도메인에는 규칙이 있음.
    • 인프라스트럭처는 데이터베이스 혹은 외부시스템과의 연계
  • 비즈니스 구현에 있어서, 중요한 규칙은 도메인에 구현되어야함.
    • 예를 들면 '배송 전에만 배송지를 변경할 수 있다' 라는 검증 로직은 도메인이 담당해야한다.
    • 왜?
    • 그게 도메인 주도..?
  • 생성자에는 반드시 필요한 것을 넘긴다.
  • 엔티티 식별자(id)를 가짐, 식별자로 구별함.
  • 밸류는 식별자 대신 다른 걸 통해, 동일성을 판단.
  • 유비쿼터스 언어. 전문가, 관계자, 개발자가 공통된 언어를 사용해서 소통과정에서의 모호함을 줄일 수 있도록..

2ch

  • 표현 계층은 응용 계층에 의존하고 응용 계층이 도메인 계층에 의존하지만, 반대로 인프라스트럭처 계층이 도메인에 의존하거나, 도메인이 응용 계층에 의존하지는 않는다.
  • 표현 -> 인프라스트럭처 이런식으로 의존하게 만들면 ,테스트 작성하거나 기능확장하기가 어렵다.
  • DIP 의존 역전 원치
    • 저순 모듈이, 고수준 모듈에 의존한다.
    • 고수준, 저수준은 상대적인 것. 만약에 도메인 - 인프라가 있으면 도메인은 고수준, 인프라는 저수준이다.
    • 구현 객체가 (JPA로 데이터를 가져올지 혹은 Drool로 가져올 지, 구체적으로 코드로 구현된 저수준 객체) 가 인터페이스에 의존하고 있는 현상 (고수준, 추상화 되어있음.) 이 DIP
    • 인터페이스를 통해 기능이 구현된 응용 계층에서는, 어떤 저수준 모듈을 사용하는 지 알 필요 없게됨.
    • 생성자로 인터페이스를 받아라 하는게 DIP를 지키고 나아가 테스트나 기능 확장을 쉽게하려는 목적
  • 엔티티
    • 고유 식별자를 갖는 객체
    • e.g 주문, 회원, 상품..
    • 단순히 데이터를 담고 있기 보다는, 데이터와 함께 기능을 제공함.
    • 밸류의 집합으로 구성될 수도 있음.
  • 밸류
    • 고육 식별자를 갖지 않는 객체
    • e.g Address, Money...
    • 불변으로 구현할 것을 권장
  • 애그리거트 aggregate
    • 엔티티와 밸류를 개념적으로 하나로 묶은 것.
    • 주문 애그리거트 = Order(도메인), OrderLine(밸류), Orderer(밸류)
  • 리포지터리 repository
    • 도메인 모델의 영속성을 처리하는 객체
    • 즉 물리적인 저장소에 도메인을 저장하기 위한 계층, 저수준 모듈로 인프라스트럭처 영역에 해당함.
    • DBMS에 저장 혹은 로딩...
  • 도메인 서비스 domain service
    • 특정 엔티티에 속하지 않은 도메인 로직을 제공.
    • 할인 금액 계산을 하기 위해선 도메인 서비스가 필요함.
  • 응용 서비스는 의존 주입등을 통해, 실제 리포지터리 구현 객체에 접근함.
  • 도메인, 응용영역에서 인프라스트럭처의 기능을 직접 사용하는 것보다, 이 두 영역에 정의한 인터페이스를 인프라스트럭처 영역에서 구현하는 것이 시스템을 더 유연하고 테스트하기 쉽게 만든다.
    • 무조건 그런것은 아님.
    • 예를 들면 @Transactional 이나 영속성을 위한 @Entity, @Table 같은 어노테이션은 응용, 도메인 객체에서 사용하는 것이 낫다.
  • ui -> application -> domain <- infrastructure
    • 패키지를 나누는 것도, 정해진 건 없다. 다만 합의가 필요한 부분.
    • 그리고 한 패키지에 너무 많은 정보를 담고 있지 않게 하는게 좋을듯. 많아지면 나누는 걸 시도.

3ch

  • 애그리거트는 복잡한 모델을 관리하는 기준을 제공.
  • 주문 애그리거트는 배송지르르 변경하거나 주문 상품 개수를 변경하는 등 자기 자신을 관리하지만, 주문 애그리거트에서 회원의 비밀번호를 변경하거나 상품의 가격을 변경하지는 않는다.
  • 'A가 B를 갖는다' 는 요구사항은 반드시 A와 B가 한 애그리거트에 속하는 것을 으미하는 건 아니다.
  • 다수의 애그리거트가 한 개의 엔티티 객체만 갖는 경우가 많았으며, 두 개 이상의 엔티티로 구성되는 애그리거트는 드물었다.
  • 주문 애그리거트는 Order 엔티티와, OrderLine 밸류로 구성된다.
  • 애그리거트 루트.
    • 애그리거트에 속한 모든 객체의 일관된 상태를 유지하려면, 관리할 주체가 필요한데 이러한 책임을 지는 것이 루트 엔티티
    • 주문 애그리거트 에서 루트는 Order 엔티티.
  • 애그리거트 외부에서, 속한 객체를 직접 변경하면 안됨.
    • 그러면 애그리거트에 속한 객체는 루트만이 관리한다는 규칙을 어기게 되는 셈.
  • 트랜잭션의 범위는 작을수록 좋다.
    • 한 트랜잭션에서는 한 개의 애그리거트만 수정해야한다.
    • 왜? 그렇게 되면, 애그리거트간의 결합도가 높아진다.
    • 결합도가 놓아지면, 향후의 수정 비용이 증가한다.
  • 필드(@ManyToOne, @OneToOne..)를 이용한 애그리거트 참조는 아래 문제를 유발할 수 있다.
    • 편한 탐색 오용, 즉 다른 애그리거트의 상태를 쉽게 변경할 수 있게 됨.
    • 성능에 대한 고민, Lazy, eager loading
    • 확장 어려움
    • 그래서 Id 참조를 고려하자
  • ID를 이용한 애그리거트 참조는 지연로딩과 같은 효과를 만든다. (N+1 문제)
  • 목록이나, 조회 기능은 조회 전용 모델을 이용해서 구현하는 것이 좋다.
  • 애그리거트가 갖고 있는 데이터를 이용해서, 다른 애그리거트를 생성해야한다면 애그리거트에 팩토리 메서드를 구현하는 것을 고려해보자
    • store의 데이터를 이용해서 product을 생성한다면,
    • store에서 product을 생성하는 팩토리 메서드를 추가하면... 좋음.

4ch

  • 리포지터리 구현 클래스는 인프라스트럭쳐 영역
  • Spring Data JPA를 사용하면 인터페이스만 구현하면 구현 객체는 스프링에서 알아서 만들어줌.
  • JPA에서 @Entity 나 @Embeddable 로 클래스를 매칭하려면 기본 생성자를 제공해야함 (public or protected..)
    • protected로 선언하면 다른 코드에서 기본 생성자를 이용하지 못하므로 권장되는 설정
  • 엔티티에 프로퍼티를 위한 공개 get/set 메서드를 추가하면, 도메인의 의도가 사라지고 객체가 아닌 데이터 기반으로 엔티티를 구현할 가능성이 높아짐.
    • setter 대신, changeStatus.. 와 같이 의도가 잘 나타나는 이름명을 사용할 수 있도록 해야함.
  • 두 개 이상의 프로퍼티를 가진 밸류 타입을 한 개 커럽에 매핑하려면.. AttributeConverter를 이용
  • 밸류 컬렉션을 별도 테이블에 매핑할 떄는 @ElementCollection, @CollectionTable 을 같이 이용함.
  • 밸류 컬렉션을 한 개 컬럼에 매핑할 때는?
    • AttributeConverter 이용
  • 식별자라는 의미를 부각시키기 위해서, 식별자 자체를 밸류 타입으로 만들 수도 있음.
    • JPA에서 식별자 타입은 Serializable 이어야 하므로, 밸류 타입으로 만들 때 해당 인터페이스를 상속 받아야함.
  • 애그리거트에서 루트 엔티티를 뺀 나머지 구성 요소는 대부분 밸류.
    • 루트 엔티티 이외에 또 엔티티가 존재하게 되는 경우, 진짜 엔티티로 필요한지 확인이 필요함.
    • 밸류를 매칭한 테이블을 지정하기 위해 @SecondaryTable, @AttributeOverride 를 이용
  • 계층 구조를 가진 밸류 타입을 구현하기 위해?
    • abstract 클래스
    • @Inheritance, @DiscriminatorColumn 이용
  • 루트 엔티티를 로딩하는 시점에 애그리거트에 속한 객체를 모두 로딩해야 하는 것은 아니다.
  • 저장, 삭제 메서드는 애그리거트 루트 뿐만 아니라, 속한 모든 객체에게 전파되어야함
  • 리포지터리와, 도메인 모델의 구현 기술은 거의 바뀌지 않는다.
    • 그러므로 도메인 모델이 구현 기술에 의존해도 괜찮음

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.