사이드 프로젝트를 하다가 깊게 고민할 거리가 생겼다.
세상에서 가장 단순한 게시판을 하나 생각해보자.
하나의 게시글은, 여러 댓글을 가질 수 있다. 따라서
게시글 : 댓글은 1:N으로 매핑되어 있다.
만약 MVC에 맞춰 코드를 작성 할 때, 댓글을 추가하는 기능을 작성하고자 한다.
댓글을 추가하고자 한다면, Post의 정보를 가져와야 한다. 그렇다면 CommentService에서, PostRepository를 참조하게 된다.
예시 코드를 보자.
@Service
@RequiredArgsConstructor
public class CommentService{
private final CommentRepository commentRepository;
private final PostRepository postRepository;
public void addNewPost(String content, Long postId){
Comment comment = new Comment();
comment.setContent(content);
comment.setPost(postRepository.getById(postId));
commentRepository.save(comment);
}
}
CommentService에서 PostRepository도 의존하고 있다.
당장은 정말 단순한 코드여서 문제가 없어보이지만, 규모가 커지며 한 서비스가 5개,6개가 넘어가는 리포지토리를 의존하게 된다면
너무 복잡해지지 않을까? 라는 고민을 갖게 되었다.
StackOverFlow에서 나온 비슷한 고민의 경우엔, "괜찮다" 의견이였다. 비즈니스 로직이 없다면 Repository를, 비즈니스 로직이 필요하다면 코드 중복 제거를 위해 Service를 의존해 사용해도 괜찮다였다.
이곳에서도 "괜찮다" 라는 의견이였다. 조금 놀라웠던건 컨트롤러에서 Repository를 직접적으로 참조해 사용한다는 경우였다. 그러면 계층 관계가 복잡해지지 않을까? 라는 고민이 또 생기지만, 아키텍쳐를 크게 해치는 구조가 아니라면 괜찮다고 간주하는 것 같다.
아키텍쳐적으로, Repository와 Service를 1:1로 매핑하고자 할 때, 찾아보니까 퍼사드 패턴 (Facade Pattern)을 적용 할 수 있을 것 같다.
이미지 출처 : https://www.happykoo.net/@happykoo/posts/266
퍼사드 패턴은, 클라이언트는 복잡하게 얽혀있는 서브시스템은 모른 채 Facade 객체에만 의존하는것이다.
우리 예시로 따지면, 하나의 서비스가 의존할 여러 Repository를 가지고 우리가 만들 Service에서 필요한 메소드를 가지게 되는, 일종의 조합 전용 객체를 만드는 방법이다.
따라서 서비스는 Facade 객체만 의존하게 되고, Facade 객체는 사용할 Repository들을 주입받는 형태로 구성된다.
코드를 짜는 시간보다는, 이러한 고민에 대한 답을 찾는 시간이 정말 긴 것 같다. 앞으로도 해나갈 고민들을 잘 정리해가자.