[DDD] SPECIFICATION(명세)

0️⃣1️⃣·2024년 2월 10일
0

DDD

목록 보기
8/22

필요성

  • 처음에는 특정 클래스에서 boolean 타입의 메소드를 추가하다가, 여러 규칙이 추가됨에 따라서 클래스의 명료함이 규칙을 평가하는 코드 덩어리에 묻혀 이내 사라져 버릴 수 있음

  • 또한 근본적인 의미를 지원하지 않는 도메인 클래스와 하위시스템에 대해 의존성을 가질 수 있음

  • 리팩토링을 목적으로 규칙을 평가하는 코드들은 응용 계층으로 옮겨질 것이며, 단순한 조건 코드로 팽창될 것이고 결국 규칙에 대한 가독성은 떨어지고 만다.

업무 규칙의 분리

종종 업무 규칙이 ENTITYVALUE OBJECT가 맡고 있는 책임에 맞지 않고 규칙의 다양성과 조합이 도메인 객체의 기본 의미를 압도할 때가 있다.

그렇다고 규칙을 도메인 계층으로부터 분리한다면 도메인 코드가 더는 모델을 표현할 수 없어서 상황이 더 악화된다.

정의

SPECIFICATION은 다른 객체에 대한 제약조건을 기술하며, 제약조건은 존재할 수도 존재하지 않을 수도 있다.

SPECIFICATION을 다양한 용도로 사용할 수 있지만 가장 기본적인 개념은 다른 객체가 SPECIFICATION에 명시된 기준을 만족하는지 검사할 수 있다는 것이다.

특별한 목적을 위해 술어와 유사한 명시적인 VALUE OBJECT를 만들어라. SPECIFICATION은 어떤 객체가 특정 기준을 만족하는지 판단하는 술어다.

단순한 명세들을 결합하도록 개념을 확정해서 사용할 수 있다.

@RequiredArgsConstructor
class Specifiaction {
	private final LoalDate dt;
    boolean isSatisFiedBy() {
    	//
    }
}

효과

  • SPECIFICATION을 통해서 규칙을 도메인 계층에 유지할 수 있음
  • 객체를 사용해서 규칙을 표현하므로 설계가 모델을 더욱 명확하게 반영할 수 있음

검증

  • 객체가 어떤 요건을 충족시키거나 특정 목적으로 사용할 수 있는지 가늠하고자 객체를 검증

선택

  • 컬렉션 내의 객체를 선택(이를테면, 기한이 만료된 송장 목록을 조회)
  • 질의문은 테이블 구조를 노출시킬 수 있는 개념이 도메인에서 발생하면 안됨
  • 인프라스트럭쳐 계층에서 질의가 생성될 수 있어야 함
Set set = repository.selectSatisFying(new ConcreteSpecifiaction(date));
public class Speicifacation {
	private final LocalDate date;
	// 기본적인 코드들
    public Set satisfyingElementsFrom(Repository repository) {
    	return repository.selectWhereDueDateIsBefore(date);
    }
}
public class Repository {
	public Set selectSatisfying(Specification spec) {
    	return spec.satisfyingElementsFrom(this);
    }
}

요청 구축(생성)

  • 생성기의 구현을 인터페이스로부터 분리할 수 있다. SPECIFICATION은 생성할 결과물에 대한 요구사항은 선언하지만 결과물을 생성하는 방법은 정의하지 않는다.

  • SPECIFICATION을 통해서 생성기의 결과물을 예상할 수 있음

  • 인터페이스는 생성기에 대한 입력을 정의하는 명시적인 방법이 모델에 포함돼 있어서 테스트하기가 수월함

public interface WareHousePacker {
	public void pack(Collection containersToFill, Collection drumsToPack)
}

0개의 댓글