Java - self-encapsulation (자가 캡슐화) 혹은 self-delegation (자가 위임)

반 버논의 도메인 주도 설계 구현(DDD Domain Driven Design)이라는 책을 요즘 보고있다. 여러가지 도움되는 개념도 많다. 그 중에 하나인 자가 캡슐화의 개념을 한 번 다뤄보겠다.

마틴 파울러 형님께서 '자가 캡슐화는 심지어 같은 클래스 내에서부터 모든 데이터로의 액세스가 접근자 메소드를 거쳐가도록 설계하는 방법이다.' 라고 말했다.

 말로만 들어선 언뜻 이해하기 어렵다.

그래서 예제를 통해서 풀어나가려고 한다.
우선 User라는 Entity = aggregate root 가 존재한다.
식별자로써 Long 타입의 id
그밖의 중요한 username, password 와 값 객체인 Person 을 가지고 있다.

중요하게 볼 것은 기본 생성자와 setter 들의 접근 제어자이다. protected 로 선언했다.
protected 로 선언한 이유는 같은 모듈안에서만 호출하도록 모듈간의 의존성을 제거하기 위함에도 있다.
더욱 강력하게 기본생성자를 private 으로 만들고, 파라미터 생성자만 protected 로 공개할 수도 있다.
그리고 setter 들도 또한 private 으로 만들어서 오직 파라미터 생성자만이 속성/특성을 설정할 수 있도록 한다면, 불변하게 만들수 있다.

또한 매개변수가 있는 생성자를 보면, 변수 할당을 자신의 내부 세터로 위임한다.
각 세터에게 상태의 일부를 설정하는 계약 조건을 결정토록 하고 있다.
각 세터는 Entity 를 대신해 개별적으로 null 이 아니라는 제약을 검사해서 인스턴스 계약을 집행한다.
이는 Assertion Guard 라고도 한다.

이 기법의 이점은 몇가지가 있다고 한다.
1. 객체의 인스턴스 변수를 추상화할 수 있도록 해준다.
2. 이를 통해 해당 객체를 담고 있는 많은 다른 객체에서 손쉽게 특성/속성을 가져오는 방법을 제공한다.
3. 또한 이를 통해 계약의 의한 설계를 이행한다.
4. 값의 불변성을 유지할 수 있다.

하지만 이 기법을 많이 사용하게 되면 예제를 통해서 알 수 있듯이, 필요이상으로 지저분해질 수도 있는 단점이 있다.



또 다른 예시로 EmailAddress 값 객체의 예제이다.

setAddress() 는 모든 전제 조건의 가드는 인수 anAddress 의 조건을 검사한다. 또한 눈여겨 볼 것이 setAddress() 는 private 접근 제어자를 사용했다. 이는 EmailAddress 내부에서만 해당 setter 를 호출할 수 있다. 따라서 오직 생성자를 통해서만 값을 설정할 수 있고, 이를 통해서 address 값을 불변으로 사용할 수 있게되는 이점이 있다.

setAddress() 의 메소드 계약에는 네 가지 조건이 있다.
1. 매개변수는 null 이 될 수 없다.
2. 매개변수는 빈 문자열이면 안 된다.
3. 매개변수는 100자 이내의 길이여야 한다. (그러나 0은 안됨.)
4. 매개변수는 이메일 주소의 기본 포맷과 맞아야 한다.

일부는 이런 종류의 전제 조건 확인을 방어적 프로그래밍(depensive programming) 이라고 부른다고 한다.

댓글

이 블로그의 인기 게시물

About JVM Warm up

About idempotent

About Kafka Basic

About ZGC

sneak peek jitpack

Spring Boot Actuator readiness, liveness probes on k8s

About Websocket minimize data size and data transfer cost on cloud

About G1 GC

대학생 코딩 과제 대행 java, python, oracle 네 번째