DDD/도메인 주도 설계 철저 입문 (26) 썸네일형 리스트형 Specification 객체 정의와 활용 - 「도메인 주도 설계 철저 입문」 13장 (1) Specifiction 객체란?한국말로 명세 객체는 어떤 객체가 특정 조건을 만족하는지 평가하기 위한 객체로, 엔티티나 값 객체의 메서드로 담기에는 복잡한 경우에 사용되는 클래스이다. 복잡한 도메인 규칙 예시여러명의 User로 이루어진 Circle이 있을 때, Circle의 최대 인원은 30명이며 프리미엄 User가 10명 이상 속하는 Circle은 최대 인원이 50명인 규칙이 있다고 치자. 도메인 규칙이 다소 복잡하여 Specification으로 구현하는 것이 적절하다. Specification을 활용하지 않으면 어떻게 될까 (1) - Repository 사용하기Circle 클래스에 `isFull`이라는 메서드가 UserRepository를 가지고 circle에 속한 user 수를 셀 수도 있겠지만.. 애그리게이트의 경계 구분하는 법 - 「도메인 주도 설계 철저 입문」 12장 (3) 애그리게이트의 예시실무에서 `Circle`과 같은 부모 클래스가 `List members`를 멤버 변수로 가지는 경우는 많이 볼 수 있다. 이 경우에 Circle과 User를 각각 하나의 애그리게이트로 볼 수 있다. class Circle { private final List members;} 애그리게이트 경계가 무너진 경우이때 Circle이 User를 인스턴스로 직접 가지고 있게 되면, 다음과 같이 Circle 애그리게이트 내부(여기서는 Circle Repository)에서 User 데이터에 직접 접근할 수 있게 된다.public class CircleRepository implements ICircleRepository { (...생략...) @Override public vo.. 애그리게이트 활용 (feat. 노티피케이션 객체) - 「도메인 주도 설계 철저 입문」 12장 (2) 노티피케이션 객체란클래스의 캡슐화를 위해 멤버 변수를 private으로 선언하면 곤란한 상황이 발생하곤 한다. 클래스의 데이터를 전달할 수가 없기 때문이다. 이럴 땐 interface와 class의 쌍으로 이루어진 노티피케이션 객체를 활용하면 된다. 노티피케이션 객체 구현먼저 인터페이스와 클래스 쌍을 다음과 같이 구현한다.public interface IUserNotification { void id(UserId id); void name(UserName name);} public class UserDataModelBuilder implements IUserNotification { private UserId id; private UserName name; @Override .. 애그리게이트란 - 「도메인 주도 설계 철저 입문」 12장 (1) 애그리게이트란? 애그리게이트는 변경의 단위이다. 11장에서 프로그래밍했던 User나 Circle과 같은 객체가 바로 애그리게이트이다. 출처 :「도메인 주도 설계 철저 입문」 애그리게이트의 특징애그리게이트는 경계와 루트를 갖는다. 애그리게이트의 경계는 애그리게이트에 포함되는 대상을 결정하는 경계이고, 애그리게이트의 루트는 애그리게이트에 포함되는 특정 객체다. 외부에서 애그리게이트를 다루는 조작은 모두 루트를 거쳐야 한다. 변경은 애그리게이트 루트를 통해서만 - 예시 (1) UserUser 애그리게이트의 루트는 User 클래스이다. 따라서 사용자명 변경도 루트인 User에 요청하는 형태여야 한다.이를 위해서 `changeName`과 같은 메소드를 만들면 null 체크 등과 같은 유효성 검사를 할 수 있.. 도메인 규칙을 코드로 제대로 표현하는 법 - 「도메인 주도 설계 철저 입문」 11장 (4) 말과 코드를 일치 시키기"써클 정원은 30명이다"라는 도메인 규칙은 다음과 같이 표현하는 것이 바람직하다. 규칙에 나오는 "30"이라는 숫자를 코드에 그대로 사용하는 것이다. // 바람직한 예 : 말과 코드가 일치한다.if (member.size() >= 30) { throw new IllegalStateException("정원 초과");} 만약 다음과 같이 말과 코드가 불일치 하게 되면 여러가지 문제가 생긴다. if (member.size() > 29) { throw new IllegalStateException("정원 초과");} 1. `30`으로 코드 전역 검색을 했을 때 코드가 나오지 않음2. 누군가 말과 다른 코드를 보고 오류라고 생각해서 29를 30으로 고칠 우려가 있음 규칙을 도.. 테스트 커버리지 높이는 법 - 「도메인 주도 설계 철저 입문」 11장 (3) jacoco 플러그인 세팅`build.gradle` 파일에 다음과 같은 내용들을 추가한다. plugins { id 'jacoco'}tasks.named('test') { finalizedBy(jacocoTestReport)}jacoco { toolVersion = "0.8.12"}test { useJUnitPlatform() finalizedBy jacocoTestReport}jacocoTestReport { dependsOn test reports { xml.required = false csv.required = false html.outputLocation = layout.buildDirectory.dir('jacocoHtm.. 엔티티 중복 확인은 도메인 서비스인가 앱 서비스인가 - 「도메인 주도 설계 철저 입문」 11장 (3) 저자의 주장 : 엔티티 중복 확인은 도메인 서비스가 해야 한다. 책에서는 엔티티 중복 확인 서비스를 다음과 같이 도메인 서비스로 구현하였다. 저자가 이렇게 한 이유는 "이름을 기준으로 중복을 판단한다"와 같은 규칙이 도메인 지식이기 때문이다. 저자는 도메인 지식은 한 곳에 모여 있어야 한다고 주장한다. 도메인에 관한 지식이 도메인 서비스에 모두 모여 있으면 유지 보수 측면에서 도메인 서비스 클래스만 확인하면 되므로 효율적이라고 볼 수 있다. public class CircleService { private final CircleRepository circleRepository; public CircleService(CircleRepository circleRepository) { .. Entity Factory 패턴 - 「도메인 주도 설계 철저 입문」 11장 (2) 팩토리 패턴 1. 기본 생성자는 private기본 생성자를 private으로 선언한다. 이렇게 하는 이유는 객체 생성을 팩토리를 통해서만 하도록 통제하기 위해서이다. 이때 주의해야 할 점은 기본 생성자를 아예 만들지 않으면 자바 컴파일러가 자동으로 기본 생성자를 생성하여 누구나 기본 생성자를 통한 User 생성할 수 있게 된다는 것이다. 따라서 생성자를 반드시 만들고, private으로 설정하는 것이 바람직하다.package com.woojoovove.ddd11.user.domain;public class User { private final UserId id; private UserName name; private User(UserId id, UserName name) { .. 이전 1 2 3 4 다음