Service 코드 간의 의존성이 걱정된다 (feat. 뭉글 개발)

gogori6565·2025년 1월 31일
0

Spring

목록 보기
3/3

방법 1: BookShelfServiceupdateUserBookTagArticleCreateService에서 직접 호출 (비추천)

가장 쉬운 방법이지만, 강한 의존성 (tight coupling)이 생길 위험이 있음.

@Service
@RequiredArgsConstructor
public class ArticleCreateService {
    private final BookShelfService bookShelfService;
    
	// 감상평 게시글 생성
    public void createReviewArticle(ReviewArticleCreateDTO reviewArticleCreateDTO, Long userId) {
    
    	...
    
    // user_book_tag 수정 사항 있을 경우, 수정
	List<UserBookTagDTO> tagList = reviewArticleCreateDTO.getUserBookTagList();
	bookShelfService.updateUserBookTag(tagList, book, null, reviewArticle);
    
    	...
    }
}

✔️ 장점: 구현이 간단함
단점: ArticleCreateServiceBookShelfService에 강하게 의존하게 되어, 유지보수 시 BookShelfService 변경이 ArticleCreateService에 영향을 줌

추천하지 않음!
다른 도메인의 Service를 직접 호출하는 것은 의존성이 강해지는 문제가 있어서, 더 나은 방법을 찾는 것이 좋음.

🤔 의존성이 왜 강해지느냐?

  1. BookShelfServiceupdateUserBookTag의 파라미터가 변경될 경우
  2. BookShelfService 가 더 이상 필요하지 않을 경우
  3. BookShelfService 가 유지보수를 위해 인터페이스 기반 구조로 변경될 경우

-> 💀 BookShelfService가 변경되면 ArticleCreateService도 반드시 수정해야 함. (따라서, 유지보수 어렵고 코드 재사용성, 확장성 떨어짐!)


방법 2: 공통 서비스 (UserBookTagService)를 만들어서 분리 (추천!)

💡 updateUserBookTagBookShelfService에만 필요한 것이 아니라면, 공통 서비스 (UserBookTagService)로 분리하는 것이 가장 좋은 방법!

1️⃣ UserBookTagService 생성

@Service
@RequiredArgsConstructor
public class UserBookTagService {
    private final UserBookTagRepository userBookTagRepository;

    public void updateUserBookTag(List<UserBookTagDTO> tagList, Book book, ReadBooks readBooks, ReviewArticle reviewArticle) {
        if (tagList != null) {
            for (UserBookTagDTO tagDTO : tagList) {
                if (tagDTO == null) continue;  // null 태그가 있을 경우 건너뛰기
                BookTag tagEnum = BookTag.fromDescription(tagDTO.getTag());

                if (tagDTO.getTagId() == 0) { // 태그 새로 저장
                    UserBookTag newUserBookTag = tagDTO.toEntity(book, tagEnum, readBooks, reviewArticle);
                    userBookTagRepository.save(newUserBookTag);
                } else { // 태그 수정
                    UserBookTag existTag = userBookTagRepository.findById(tagDTO.getTagId())
                            .orElseThrow(() -> new NotFoundException(ErrorStatus.TAG_NOT_FOUND_EXCPETION.getMessage()));

                    // 1) 태그 이름 변경 O -> 데이터 변경 (변경 X -> 그대로 유지)
                    if (tagEnum.getId() != existTag.getTag()) {
                        UserBookTag updatedTag = tagDTO.update(existTag, tagEnum);
                        userBookTagRepository.save(updatedTag);
                    }
                }
            }
        }
    }
}

2️⃣ BookShelfService에서 UserBookTagService 사용하도록 변경

@Service
@RequiredArgsConstructor
public class BookShelfService {
    private final UserBookTagService userBookTagService;

   @Transactional
    public void updateReadBookshelf(ReadBooksDTO readBooksDTO, Long id, Long userId){
		...
    
    // 태그 수정
	List<UserBookTagDTO> tagList = readBooksDTO.getUserBookTagList();
        userBookTagService.updateUserBookTag(tagList, existingReadBooks.getBook(), existingReadBooks, null);
    
    	...

	}

}

3️⃣ ArticleCreateService에서도 UserBookTagService를 사용

@Service
@RequiredArgsConstructor
public class ArticleCreateService {
    private final UserBookTagService userBookTagService;

	// 감상평 게시글 생성
    public void createReviewArticle(ReviewArticleCreateDTO reviewArticleCreateDTO, Long userId) {
    	...
    
    // 태그 수정
	List<UserBookTagDTO> tagList = reviewArticleCreateDTO.getUserBookTagList();
	userBookTagService.updateUserBookTag(tagList, book, null, reviewArticle);
    
    	...
    }
}

🚀 결론

방법 1: BookShelfService에서 직접 호출 (비추천)

  • BookShelfServiceArticleCreateService가 서로 강하게 묶여 있어 유지보수가 어려움

방법 2: UserBookTagService를 만들어 분리 (추천!)

  • updateUserBookTagBookShelfServiceArticleCreateService에서 모두 사용하므로, 공통 기능을 UserBookTagService로 분리
  • 이렇게 하면 서비스 간 의존성이 낮아지고, 코드 재사용성이 좋아짐

📌 이렇게 분리하면 유지보수성이 높아지고 확장성이 좋아진다! 🚀

profile
p(´∇`)q

0개의 댓글