본문 바로가기

MY개발생각

[개발생각] 도메인VO를 컨트롤러의 입력파라미터로 써도될까?에 대한 고민

개발자의 욕심은 끝이 없으니, 재사용, 재사용이라는 프레임에 갇히고, 또 의미를 잃어버리고...

 

도메인VO를 정의할때, 대부분 그냥 Value Class (코틀린)로 정의해서 사용한다.

즉, 대부분은 단순 Wrap 클래스로만 VO를 정의하고 사용한다.

 

타입 안정성명시적 의미부여에 큰 의미를 둘 수 있기에, Wrap 클래스 정도만이여도 상당히 강력하다고 생각하기 때문이다.

하지만, 좀더 서비스가 복잡해지고 방대해 진다면, (즉, 다뤄야하는 도메인이 많아진다면)

VO가 다양해지고, 해당 VO의 값에 대한 벨리데이션 검증 로직을 VO로 빼는 경우도 많게 된다.

 

예를 들면

Value Class Email(value:String) {

     init {

          //value 검증 로직. (Email포멧 검증, 비즈니스 로직 검증등등) 문제있으면 예외 발생

     }

}

이렇게 도메인VO에 값에 대한 검증로직을 넣게 되면, 해당 VO 생성시, 값에 대한 검증이 되고, 재사용도 가능하니, 편하다.

그리고, 욕심도 하나 생긴다...

해당 VO를 application 레이어의 컨트롤러의 입력파라미터로 사용하면, 검증도 동일하게 할수있으니, 일석이조아닐까?? 라고...

 

물론, DDD의 의미에 따르면,

Application 레이어에서의 Email의 검증은 단순 값 (NotBlank),형식등의 검증만 구현되어야 하고,

도메인VO에서의 Email의 검증은 비즈니스 로직상에서 필요한 데이터의 값의 검증으로 이원화 되어,

관리되어야 이상적이라는건 이미 인지하고 있다.

어플리케이션 레이어와 도메인 영역에서의 비즈니스 로직은 명확히 연관이 없게 해야하며, 별개로 관리해야한다가 전제조건이기 때문이다.

 

하지만, 그건 말그대로 이상적인 이야기인것같다고 문득 생각이 들었다.

 

Email값 검증의 룰이 값의 검증과 비즈니스 로직의 검증으로 나눠지는 경우가 실무에서 얼마나 있을까??

다른 입력값들 또한 그렇게 명확히 구분되고 나눌수 있는 경우가 얼마나 될까? 생각해보면, 그 케이스는 거의 없을것 같다는 생각이 든다.

 

그럼, 여기서 의문점이 생긴다....

 

어플리케이션레이어에서 도메인VO를 스리슬쩍, 사용해도 될까?!

더 정확히는 도메인 VO에 구현된 값 검증 벨리데이션 로직을 어플리케이션에서도 사용해도될까? 라는 의문이다..

 

이렇게 되면 장점은,

어플리케이션 레이어에서 잘못된 값이 입력될때, 실제 서비스 레이어까지 도달하지않고, 바로 예외를 발생시키기에 불필요한 연산/리소스 낭비가 없게 된다.

도메인 서비스 영역까지 오기전에 이미 값검증에서 예외가 발생하기때문이다.

 

이 부분은, 성능/리소스/속도/효율 등에 미친 개발자에게는 또 엄청난 매력으로 다가오는 부분이기도 하다. (내가..그 미친개발자중에 하나..)

뭔가 합리적이고, 현실타협점에서 선택된 쿨한 방법 같아보이기도 한다.

 

그런데...

고민끝에 어플리케이션 레이어에서 도메인VO의 검증룰은 재사용하지 않기로 맘먹었다. (정말 생각 많이 한거같다)

도메인 주도개발은 사실, 눈에 보이는 옅은 효율성을 넘어서,

 

서비스들의 영역을 명확히 분리하고,

설령, 비슷한 개념의 코드가 각각의 영역에 중복 존재한다고 하여도, 그 부분을 상쇄할수있는 독립성이 지켜진다면,

기꺼이 그렇게 하겠다는 의지에서 시작한다고 생각한다.

 

중복 개념의 객체가 존재한다고 하여도, 사실은 그 각각은 각자의 변경에 독립성을 부여받았기 때문에, 추후에는 서로가 달라질 확률과 기회가 있는 객체들이고 개념이다.

즉, 엄청나게 확장에 열려있고 수정에 닫혀있게 된다는 뜻이다.

 

도메인VO 또한 이런 개념으로 생각한다면, 검증로직을 같이 사용하는건 그 확장을 닫히게 하는 시발점이 될수도있다.

 

하나 예를 들어보면,

어플리케이션 레이어에서 컨트롤러의 입력파라미터중에 email:String이 존재하고, 도메인Vo에 EmailVo가 존재한다고 하면,

 

email -> 검증은 NotBlank, 이메일 형식 검증등

EmailVo -> 이메일 도메인에 대한 검증 (kakako.com이메일만 허용), email이 포워딩 이메일인지에 대한 검증, 이메일의 형식이 해당 서비스에서 만들어준 형식만 정상으로 보는 케이스등

 

이런식으로 분리를 하는게 맞다.

 

미래에는 (서비스를 유지보수하면서) 해당 도메인 영역에서 EmailVo가 하나만 존재한다고 장담 할수없기 때문이다.

PrivateEmailVo, PublicEmailVo, CorpEmailVo등 비지니스 요구사항이 반영된 VO가 여러개 생길수있고,

이 각각의 의미는 도메인의 비즈니스 로직과도 타이트하게 연관이 될수가 있다. 

따라서, 해당 검증을 어플리케이션 레이어에 넣게 되면,

도메인 비즈니스 로직이 어플리케이션 레이어와 타이트하게 엮일 확률이 커지며,

Email이라는 단순 파라미터의 의미가, 앞단에서 비즈니스 개념으로 세분화 되고, 다양해지게 되버린다..

 

당장, API 문서기술에서도 아마 혼란이 올것이다.

 

따라서 어플리케이션 영역에서는 좀더 표준적인 의미로 값을 받고,

도메인쪽으로 해당 값을 넘길때는 도메인VO를 통해, 비즈니스 의미가 담긴 데이터로 검증후 변환된 데이터를 사용하는 흐름을 취하는게, 맞는 방향이라고 생각했다.

 

뭐, 하지만 개발이라는건 100% 답이 없는 행위중에 하나니, 내가 생각한게 100%맞다고는 할수없겠다..

하지만,

정답은 아니라도, 올바른 방향정도는 되지 않을까? 생각해본다. :)