Spring MVC

springmvc.egloos.com


포토로그


Service

도메인 주도 설계에서 말하는 'Service'란 근본적으로 'Entity'나 'Value Object'와 다르지 않다. 물론 다르지 않다는 개념 자체가 'Service'가 데이터 단위로 활용된다거나 일정한 값을 가지고 있다는 뜻은 아니고 동일하게 도메인 레이어 (또는 계층)에서 'Entity'나 'Value Object'와 같은 오브젝트 따위로 취급되는 것을 일컫는다.

이게 개념은 말처럼 쉬운데 사실 기존의 개발풍토에 익숙한 개발자라면 실질적으로 깨닫고 코드로 옮기기까지 매우 많은 시행착오를 겪을 수 있다. 왜냐하면 보통 개발환경에서 통념 상 'Service'는 하나의 계층으로 'DAO' 계층에서 작성된 오브젝트를 근간으로 크리티컬한 로직을 작성하거나 처리하는 용도로 사용되곤 하지만 도메인 주도설계에서 'Service'는 객체의 행위 또는 활동을 표현하는 단위로 사용되기 때문이다.

필자가 겪은 시행착오를 하나 살펴보자. 다음의 코드는 처음 서비스 오브젝트를 만들 때 습관적인 개발방식에 따라 작성한 서비스 인터페이스이다.
public interface UserService {
User add(User user);
User update(User user);
void remve(User user);
...
}

좀 급하게 만드느라 약간 'DAO (Data Access Object)'스런 코드를 만들긴 했지만 어찌됬든 일반적인 개발환경의 관점에서 바라보자면 위의 코드는 충분히 서비스 계층에서 끌고 나갈 수 있는 코드이기도 하다. 이런 코드를 도메인 주도설계에서는 맹목적인 서비스라고도 하는데 서비스 자체가 하나의 도메인 오브젝트('Entity' 또는 'Value Object')에 종속적이고 행동이나 활동에 근간을 두지 않고 'Management'의 성격을 띄게 때문이다.

도메인 주도설계에서는 이러한 'Management', 즉 생존주기와 관련된 것들은 도메인 스스로가 결정하게 되어있으며 이것을 기존의 코드 방식처럼 다른 서비스 또는 'DAO'에 위임하는 것을 지향하지 않는다.

그렇다면 위의 코드를 도메인 주도설계 목적에 맞게 바꾸어 본다면 어떻게 바뀔 수 있을까? 아마 아래와 같이 작성할 수도 있겠다.

public interface AccountService {
User register(final String email, final String password);
User unsubscribe(final User user);
...
}

필자는 위의 'UserService'를 'AccountService'로 바꾼 다음에 그 성격을 사용자의 생존주기에 대한 행위를 기준으로 작성하였다. 서비스를 작성할 때 주의해야 할 점은 자신이 만든 메서드를 직접 소리내어 말해보았을 때 이것이 어색함없이 받아들일 수 있어야 하는데 도메인 주도설계가 줄곧 말하는 유비쿼터스 언어의 특성을 살리기 위해서도 그러하고 기본적으로 좋은 메서드를 만드는 좋은 방법 때문이기도 하다.

'register' 메서드와 'unsubscribe' 메서드를 소리내어 말해보자. 각각 "이메일과 패스워드로 사용자를 등록합니다.", "사용자를 탈퇴시킵니다."라고 말할 수 있겠다. 그리고 이런 방식으로 서비스를 작성하다보면은 서비스가 특정 도메인에 종속되지 않고 독립적인 성격을 띈 도메인 오브젝트로 만들어낼 수 있다.

물론 도메인 주도설계 방식으로 'Service'를 만들 때 주의해야 할 점은 'Entity' 또는 'Value Object'에서도 충분히 다룰 수 있는 기능들을 모조리 'Service'로 제작해서는 안된다는 것이다. 보통 많은 개발자들이 도메인 오브젝트에 어떠한 로직을 집어넣기 보단 빈약한 도메인 오브젝트 방식(프로퍼티와 'get...', 'set...' 으로 캡슐화만한 오브젝트)으로 작업해오다보니 도메인에 어떠한 로직이 들어가야 올바른지 헷갈려 하는 경우가 많다. 게다가 도메인 주도설계는 아키텍터, 또는 어플리케이션 특성에 따라 매우 주관적인 코드가 될 수 있으므로 이런 로직들에 대해서는 개발자들 간의 충돌이 일어날 수도 있고, 어떠한 부분에서는 매우 애매모호한 경우가 발생하여 개발에 차질을 빚기도 한다.

이러한 상황에서 명확한 기준은 가급적 'Entity', 'Value Object'. 특히 'Root Entity'에 대해서는 'Aggregate' 경계 내의 오브젝트에 대한 통제 권한을 스스로 관리하게끔하고 그 이외의 서로 다른 'Aggregate'를 가진 도메인 끼리에 대해서는 서비스로 제작하여 처리하는게 올바른 듯 하다.

오일러의 아름다운 정리

그동안 오일러의 아름다운 정리를 증명하기 위해 했던 수학 스터디의 대단원.제법 싱겁게 끝나긴 했지만 처음부터 모든 과정의 증명을 통해 이뤄낸 결과였던 터라 기념으로 영상 제작하였다. » 내용보기

정말 오랜만에 쓰는 글.

최근에 회사업무로 바빠서 몇달간 글을 쓰지 못했다. 사실 업무도 업무였거니와 지식이 바닥났다는 사실도 한몫했지만..앞으로 몇달동안 하이버네이트와 도메인 주도설계에 대한 깊은 학습 결과를 글로 옮겨봐야겠다. » 내용보기

Entity와 Value Object

사실 이 두가지 개념을 어떻게 풀어 나가야 할지 참으로 난해하다. 왜냐하면 'Entity'와 'Value Object'는 개발자가 어떤 관점에서 바라보느냐에 따라 이리도 될 수 있고 저리도 될 수 있는 참 모호한 개념이기 때문이다.Entity일반적으로, entity란 존재하는 것, 즉 실체를 의미한다. 이 용어의 어원은 라틴어의 ens에서 나왔으며, 사... » 내용보기

에릭 에반스가 말하는 DDD(Domain Driven Design)

전 세계 DDD(Domain Driven Design) 그룹을 이끌고 있는 에릭 에반스가 4년의 퇴고 끝에 출판한 도메인 주도 설계에는 마틴 파울러의 다음과 같은 추천사가 담겨 있다.에릭 에반스는 도메인 모델을 잘 만들어 낼 수 있는 몇 안 되는 사람 중 하나다. 난 이 사실을 에릭과 함께 일하면서 알게 됐는데, 이때가 바로 자신보다 실력이 더 뛰어난 ... » 내용보기