코딩블로그
[리팩토링]InteliJ를 활용하여 멀티모듈 패키지 의존성 사이클 검사 및 개선 본문
우아한 객체지향 by 우아한형제들 개발실장 조영호님 강연을 보고 정리하신
https://jaehoney.tistory.com/311
님의 블로그를 보고 팝콘메이트의 패키지 의존성에 대한 검사를 하려고 한다.
서버를 혼자 구축하기도 하였고 분명 패키지 의존성 사이클이 있을 것같아 검사해보기로 하였다
무엇보다 멀티모듈을 사용하여 순환 참조문제에 대해 검토를 해보는 겸 진행해보았다.
의존성
클래스 의존성의 종류
연관관계 : A클래스에서 B클래스로 갈 수 있는 경로
의존관계 : 일시적으로 협력을 맺고 헤어지는 관계
상속관계 : A가 B를 상속하는 관계. B가 바뀌면 A가 바뀌는 것
실체화 관계 : 인터페이스와 클래스의 관계
패키지 의존성
패키지에 포함된 클래스 사이의 의존성
좋은 패키지 의존성을 설계하기 위한 규칙
1. 양방향 의존성을 피하라
2. 다중성이 적은 방향을 선택하라
3. 의존성이 필요 없다면 제거하라
4. 패키지 사이의 의존성을 사이클을 제거하라
Analyze Cyclic Dependencies(feat. IntelliJ)
InteliJ에서 패키지 의존성 사이클을 검사해주는 기능이 존재한다
이렇게 접근하면 된다
나는 전체 모듈들 사이에서의 순환참조부터 먼저 검사하고 싶었기 때문에
이렇게 진행하였다
결과:
(아이고;;)
그래서 나는 바운디드 컨텍스트 간 의존성 사이클을 끊기 위해 노력해 보았다.
먼저 나는 User, UserScreening, ScreeningReview사이에서 사이클을 끊어보려고 하였다.
하지만 설계상 저 엔티티 간에 의존성 사이클이 생기지 않는데 왜 순환이 생기는거지?라는 의문이 들기 시작해서 하나하나 분석하면서 어디에서 무엇이 의존되고 있는지 보았다.
문제점 1
Domain 모듈에 common디렉토리를 두었는데, 여기에다가 Screening에 관련된 스케쥴링을 두고 있어서 패키지 순환 사이클이 발생하고 있었던 것이다.
해결책
그래서 ScheduleService를 Screening디렉토리의 클래스로 두었더니 User, UserScreening, ScreeningReview사이에서 사이클이 없어졌다. 패키지의 위치에 대한 중요성을 뼈저리게 느낀 삽질이었다.
문제점 2
Fcm <-> User 사이에서 순환 참조가 발생하고 있었다
해결책
User의 저 코드를 삭제하였다
FcmService의 코드 변경 전
FcmService의 코드 변경 후
너무 기본적인 실수를 해버려서 할말이 없긴 하지만 앞으로는 다시는 이런 실수 안 할 각오를 다짐했다.
사실 주어진 시간안에 끝내다 보니 이런 실수를 하는 것 같은데, 요새 클린 코드 서적 리뷰를 하면서 본 구절이 있는데 이번에 또 생각이 났다.
서두르기 위해 나쁜 코드를 짠다 → 아니다! 빨리 가기 위한 유일한 방법은 언제나 코드를 최대한 깨끗하게 유지하는 습관이다
명심하자!
+추가로 내가 적용한 것은 아니지만 위에 영상과 블로그에 정리해 주신 의존성 사이클 종류와 문제점에 대한 해결책들을 정리해 보았다
Bounded Context 간 Dependency Cycle
1. 객체 참조와 ID 참조
연관 관계의 종류는 대표적으로 객체 참조 방식과 ID 참조 방식이 있고 객체 참조 방식은 연관 관계 중 가장 높은 결합도를 가진다.
객체 참조의 여러가지 문제점
- 도메인 간의 결합도 상승
- 성능 이슈가 발생하기 쉽다. (모든 도메인을 한 번에 조회가 가능할 수도 있다.)
- 수정할 도메인의 경계 및 트랜잭션 경계가 모호해진다.
- 패키지 의존성 사이클이 돈다.
2. 이벤트 전파
3. 중간 객체 / DIP 활용
(내가 팝콘메이트에서 중간 객체/DIP를 활용하여 엔티티 및 패키지 관계를 짜서 딱히 객체 참조에서 ID 참조로 바꿀 필요가 없었다!)
Bounded Context 내부의 Dependency Cycle
Validator와 Adaptor에서 의존성 사이클이 발생하고 있었다
해결법
- Valdiator의 패키지를 Adaptor으로 이동(Move)한다.
- 패키지의 양방향 의존을 끊는다.
난 전자의 방법을 택하여 Adaptor디렉토리 밑에 Validator파일을 이동하였다.
이렇게 하면 Adaptor가 Validator에 의존하지만 Validator는 Adaptor에 의존하지 않게 되고 이는 의존성을 단방향으로 만들어서 사이클을 해결하는 방법 중 하나이다.
결과로는 의존성 사이클이 다 제거된 것을 볼 수 있다
'PopcornMate' 카테고리의 다른 글
멀티 모듈 환경에서 내가 만든 api 테스트해보기 Feat. MockMvc, profileResolver, WithCustomUser (0) | 2024.03.24 |
---|---|
[Spring] FCM 구축하기 & FCM과 @Scheduled을 이용하여 특정 시간대에 알림 보내기 (4) | 2024.03.11 |
[Spring] Amazons S3 Presigned Url 구현하기 (0) | 2024.03.11 |
[Spring] 검색기능-QueryDsl로 무한스크롤로 넘겨주기 (0) | 2024.02.14 |
[인프라] 멀티모듈 적용기 (1) | 2024.02.08 |