POEAA : 분산 패턴

원격 파사드

가는 입자 객체에 대한 굵은 입자 파사드를 제공해 네트워크 상 효율을 향상시킨다.

원격 파사트 예시

객체 지향 모델은 가능하면 작은 객체(Thin interface)일 때 유연성이 높아진다. 하지만 프로세스 간 또는 네트워크 간 호출일 시에는 작은 객체 일 경우 호출 비용이 매우 커진다.

그래서 원격 객체를 사용할 경우에는 굵은 입자 파사드[GoF]가 필요하게 된다

원격 파사드가 하는 일은 굵은 입자 메서드를 가는 입자 객체로 변환하는 것이다.

작동원리

파사드를 한 번 호출 하면 파사드가 도메인 객체를 여러번 호출할 수 있다.

간단한 경우 위 예시 그림과 같이 일반적인 주소 객체의 접근 및 설정 메서드 전체를 대량 접근자(bulk accessor)라고 하는 접근자 메서드와 설정자 메서드 하나로 대처한다.

복잡한 경우 여러가는 입자 객체의 원격 게이트웨이 역할을 할 수 있다. 예를 들면 주문 파사트 하나로 한 주문과 해당 주문의 모든 주문 품목, 그리고 경우에 따라서 약간의 고객 데이터까지 얻고 업데이트할 수 있다.

세분성(granularity)은 원격 파사드와 관련된 가장 까다로운 문제 중 하나다.

어느정도로 세분화 시킬것인가? 이슈인데,

  1. 유스케이스당 하나씩 작게 여러개의 파사드를 만드는 방법
  2. 상대적으로 일반화 시켜서 굵은 입자로 적은 수의 파사드를 만드는 방법 - 이 방법을 더 추천

파사드는 내부 시스템이 아닌 외부 사용자의 편의를 위해 설계된다. 따라서 클라이언트 프로스세스가 이러한 명령이 다른 명령이라고 판단한다면 내부적으로 동일한 명령이라도 다른 명령으로 취급된다.

다른 역할

  1. 보안(ACL) 적용
  2. 트랜젝션 제어 적용

원격 파사드를 사용할 때 가장 큰 실수는 도메인 논리를 삽입하는 것이다.

원격 파사드는 도메인 논리가 아니다

파사드는 최소한의 역할만 포함하는 얇은(thin) 포장이어야 한다. 단지 도메인 논리를 호출할 뿐이다.

데이터 전송 객체(DTO)

메서드 호출 횟수를 줄이기 위해 프로세스 간에 데이터를 전송하는 객체

데이터 전송 객체

일반적으로 다수의 필드, getter, setter를 포함하는 단순한 구조를 가진다. 데이터 전송 객체(이하 DTO)는 네트워크 상에서 한 번의 호출로 많은 정보를 전송하기 위해 설계됐으며, 분산 시스템을 구현하는 핵심적인 개념이다.

원격 파사드와 비슷한 개념으로 DTO도 한동한 사용할 모든 데이터를 가져와야 한다. 원격 호출의 지연 비용을 감안할 때 여러번 추가로 호출하는 것보다는 필요 이상의 데이터를 한번에 전송하는 것이 낫다.

일반적으로 도메인 객체를 전송하기에는 힘든 경우가 많다.

  • 직렬화가 어려움
  • 모델 상 복잡한 연관관계
  • 필요없는 도메인 모델의 포함

그 대신 DTO를 통해서 도메인 객체에서 단순화된 형식의 데이터를 전송해야한다.

DTO는 특정 클라이언트의 필요성에 맞게 설계하는 것이 이치에 맞다.

  • DTO가 뷰(웹페이지, GUI)에 대응되는 경우가 많다.
  • 비슷한 DTO가 여러 화면에서 요구된다면 가능한 하나의 DTO로 통합하는 것이 좋다. (일반화 + 재사용성)

어떤 방식이 좋을까?

예를 들면 대부분의 상호작용에 특정한 DTO 하나를 사용하거 한두 개의 특정 요청과 응답에는 다른 DTO를 사용할 수 있다.

가능하다면 DTO를 단순하게 불변객체로 만드는 것도 좋다고 본다. 단 값객체(VO)와는 구별해야 한다. 중요한 것은 구조가 아니라 객체를 사용하는 목적이다.

DTO의 대안

범용 컬렉션 자료구조를 대안으로 사용하는 경우가 있다.

  • 배열 : 가독성을 해치므로 사용하지 마라
  • 딕셔너리(Map) : 그나마 나은 대안이긴 하나 아래와 같은 단점이 있다. (개인적으로 비추)
    • 명시적 인터페이스를 잃음 (DTO 특정 클래스가 없음)
    • 타입안정성을 잃음 (어떤 타입이라도 get, set이 가능해짐)

개인적으로 아주 특수한 상황을 제외하면 사용하면 안되는 안티 패턴으로 분류한다.

직렬화

  • 이진
  • 텍스트(xml, json 등)

중요한 것은 직렬화, 역직렬화가 가능하고 호환성과 플랫폼 이식성을 가지는 것이다.

도메인 객체와 DTO 간 조립

도메인객체와 DTO는 상호간 의존성을 가지는 것은 안 좋음

따라서 도메인 모델로 부터 DTO를 생성하고 DTO로 부터 모델을 업데이트 하는 별도의 어셈블러 객체를 만드는 것이 좋다.

어셈블러 객체를 사용해 도메인 모델과 데이터 전송 객체를 서로 독립적으로 유지할 수 있다.

개인적으로 DTO의 속성이 중요하지 행위가 중요하지 않으므로(정확하게 데이터만 클라이언트와 통신되면 됨) 도메인 객체에 의존하는 것은 괜찮다고 봄. DTO 생성자로 도메인 객체를 받아서 생성하거나 as 와 같은 메서드를 통해서 도메인 객체로 반환하는 것이 구현 편의성을 제공하는 것 같음. 특별하게 복잡한 경우가 아니면 조립(Assembler) 객체를 생성할 필요가 없다고 판단함.

MJ

MJ
Backend 개발자 사람입니다. 어플리케이션의 복잡성을 다루는 DDD에 관심이 많습니다. 어제보다 더 나은 개발자가 되려고 항상 노력합니다.

spring boot 2.4.x 에서 openfeign + hystrix 통합하기

spring-boot 2.4.x spring-cloud 2020.x 의존성 상황에서 feign.hystrix.enabled=true가 안됨`feign.circuitbreaker.enabled=true` 로 바꿔보지만 openfeign과 hystr...… Continue reading

IDDD 14장. 애플리케이션

Published on June 19, 2018