💡 개요
보통 개발할 때, Service 계층에 너무 많은 Repository 를 의존하고 있으면 뭔가 찝찝하다..
단일 책임 원칙을 지키지 못한 느낌..?
이러한 상황을 조금이나마 해결할 수 있는 Facade 패턴이 있다.
오늘은 Facade 패턴에 대해 정리해보자.
📕 Facade 패턴
Facade 패턴이란 시스템의 복잡한 구조를 쉽게 볼 수 있고, 사용하도록 설계한 패턴이다.
역시나 말만 들으면 이해하기 어렵다.
다음은 Facade 패턴이 적용되지 않은 BoardService 이다.
@Service
@RequiredArgsConstructor
public class BoardService {
private final MemberRepository memberRepository;
private final BoardRepository boardRepository;
private final CommentRepository commentRepository;
private final CategoryRepository categoryRepository;
private final FileRepository fileRepository;
...
}
@SpringBootTest
class BoardServiceTest {
@Autowired
private MemberRepository memberRepository;
@Autowired
private BoardRepository boardRepository;
@Autowired
private CommentRepository commentRepository;
@Autowired
private CategoryRepository categoryRepository;
@Autowired
private FileRepository fileRepository;
...
}
총 5개의 Repository를 의존하고 있다.
만약 게시판 기능에 추가할 사항이 생긴다면 의존관계가 더 많아질 수 있다.
이러한 구조는 유지보수도 어렵게 만들고, 테스트 코드 작성도 어렵게 만든다.
이전에 TDD 관련 영상에서도 봤듯이, 테스트하기 어려운 코드는 애초에 잘못 설계된 코드일 가능성이 높다는 것이다.
그렇다면 위 코드에서 Facade 패턴을 도입하면 어떻게 될까?
@Service
@RequiredArgsConstructor
public class BoardService {
private final BoardFacade boardFacade;
public BoardDetailResponse getBoard(Long boardId) {
return boardFacade.getBoardDetail(boardId);
}
...
}
@Service
@RequiredArgsConstructor
public class BoardFacade {
private final MemberRepository memberRepository;
private final BoardRepository boardRepository;
private final CommentRepository commentRepository;
private final CategoryRepository categoryRepository;
private final FileRepository fileRepository;
@Transactional(readOnly = true)
public BoardDetailResponse getBoardDetail(Long boardId) {
Board board = boardRepository.findById(boardId)
.orElseThrow(() -> new IllegalArgumentException("게시글을 찾을 수 없습니다."));
List<Comment> comments = commentRepository.findByBoardId(boardId);
List<File> files = fileRepository.findByBoardId(boardId);
Category category = categoryRepository.findById(board.getCategoryId())
.orElseThrow(() -> new IllegalArgumentException("카테고리를 찾을 수 없습니다."));
Member writer = memberRepository.findById(board.getWriterId())
.orElseThrow(() -> new IllegalArgumentException("작성자를 찾을 수 없습니다."));
return BoardDetailResponse.of(board, writer, category, files, comments);
}
...
}
@SpringBootTest
class BoardServiceTest {
@Autowired
private BoardFacade boardFacade;
...
}
BoardService 에 있던 의존관계가 모두 BoardFacade 클래스로 이동하였다.
이렇게 되면 BoardService 코드의 가독성도 올라가고, 의존관계를 오직 BoardFacade 를 통해 통제할 수 있게 된다.
또한 테스트 코드에서도 복잡한 의존관계를 직접 선언해주지 않아도 된다.
👨🏻💻 참고
https://katfun.blog/posts/하나의-Service가-여러-Repository에-의존할-때/
'개발 일기' 카테고리의 다른 글
[개발 일기] 2025.02.19 - 서브 도메인 (0) | 2025.02.19 |
---|---|
[개발 일기] 2025.02.18 - 한글과 VARCHAR (0) | 2025.02.18 |
[개발 일기] 2025.02.16 - Transaction Synchronization (0) | 2025.02.16 |
[개발 일기] 2025.02.15 - Security Context (0) | 2025.02.15 |
[개발 일기] 2025.02.14 - 우선순위 큐 (0) | 2025.02.14 |