Facade 패턴으로 의존 복잡성을 줄여보자!

혁콩·2024년 6월 11일

모두의 음악

목록 보기
5/17
post-thumbnail

들어가기에 앞서

기존 그룹 인원 체크 로직은 아래와 같았다.

해당 그룹의 활성화된 프로필 개수를 조회

만약 특정 그룹에 가입한 사람이 10,000명이라고 가정해보자. 가입 프로세스를 진행하기 위해선 10,000개의 레코드를 읽어야 하며, 시간이 지날 수록 더욱 늘어날 것이다. 이에 group 테이블에 profile_count 라는 컬럼을 추가해 로직을 변경했다.

group 테이블의 profile_count를 조회

자연스럽게 서비스 로직 또한 GroupService 로 이관했고, 기존 로직에서 호출하는 메소드만 변경해주었다.

이러한 과정에서 발생한 문제와, 해결 과정에 대해 적어볼까 한다.

문제

1. 순환 의존 문제


로직 변경 전 의존 관계를 살펴보자. GroupService가입 요청 의 존재 여부에 따라 중복 가입 요청에 대한 처리를 진행한다.

각 서비스는 ProfileService 의 인원 검사 로직을 호출하고 있다.

    @Transactional(readOnly = true)
    public void checkGroupSize(Group group) {
        if (profileRepository.countByGroupIdAndState(
        	group.getId(), State.GENERAL) >= group.getGroupSize()) {
            throw new GroupFullException(
            	"최대 인원인 그룹입니다. id : " + group.getId());
        }
    }


변경 후의 의존 관계를 살펴보자. ProfileService 가 사라지고, 그 자리를 GroupService 가 차지했다. 문제는 두 서비스가 서로 순환하는 의존 관계가 발생했다는 것이다.

순환 의존 문제 발생!!
The dependencies of some of the beans in the application context form a cycle:

   groupController defined in file 
┌─────┐
|  groupService defined in file 
↑     ↓
|  groupJoinRequestService defined in file 
└─────┘

2. 복잡한 의존 관계

위 다이어그램에선 최소한의 의존 관계만을 표시했지만, 보다 많은 의존 관계가 엮여있고, 어플리케이션 규모가 커진다면 더욱 복잡해질 것이다.

3. 분산된 관심

현재 그룹에 가입하기 위해선 GroupService 를 통해 즉시 가입하거나, GroupJoinRequestService 에서 그룹 가입 요청을 승낙해야 한다.

해결

Facade Pattern이란?

Facade, 퍼사드라고 읽는 이 패턴은 어떤 패턴일까? Wikipedia엔 다음과 같이 나와있다.

Facade (외관)는 "건물의 정면"을 의미한다.

퍼사드 패턴은 말 그대로 복잡한 시스템을 간단하게 사용하기 위해 제작되는 인터페이스이다.

도입으로 얻은 이득

1. 응집도 상승

분산된 관심이라는 말이 적절한지는 잘 모르겠다만, 그룹 가입이라는 하나의 관심이 GroupServiceGroupJoinRequestService 두 서비스 클래스에 분산되어 존재한다는 의미로 작성하였다.

두 클래스에 나눠져 존재하는 그룹 가입이라는 기능을 추출하여 하나의 퍼사드 클래스로 작성함으로써 응집도를 높였다.

2. 의존 복잡도 감소

분산된 그룹 가입이라는 관심은 GroupServiceGroupJoinRequestService 모두에게 불필요한 의존을 만들었다.

이를 하나의 퍼사드 클래스로 추출함으로써 기존 클래스들의 불필요한 의존 관계가 사라지고, 복잡도가 감소했다.

참고 자료

eungding - [클린 아키텍처] 의존성 순환 (cyclic dependency) 의 문제와 해결방안
Inpa Dev - 퍼사드(Facade) 패턴 - 완벽 마스터하기

profile
아는 척 하기 좋아하는 콩

0개의 댓글