BookShelfService
의 updateUserBookTag
를 ArticleCreateService
에서 직접 호출 (비추천)가장 쉬운 방법이지만, 강한 의존성 (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);
...
}
}
✔️ 장점: 구현이 간단함
❌ 단점: ArticleCreateService
가 BookShelfService
에 강하게 의존하게 되어, 유지보수 시 BookShelfService
변경이 ArticleCreateService
에 영향을 줌
❗ 추천하지 않음!
다른 도메인의 Service를 직접 호출하는 것은 의존성이 강해지는 문제가 있어서, 더 나은 방법을 찾는 것이 좋음.
🤔 의존성이 왜 강해지느냐?
BookShelfService
의updateUserBookTag
의 파라미터가 변경될 경우BookShelfService
가 더 이상 필요하지 않을 경우BookShelfService
가 유지보수를 위해 인터페이스 기반 구조로 변경될 경우-> 💀 BookShelfService가 변경되면 ArticleCreateService도 반드시 수정해야 함. (따라서, 유지보수 어렵고 코드 재사용성, 확장성 떨어짐!)
UserBookTagService
)를 만들어서 분리 (추천!)💡 updateUserBookTag
가 BookShelfService
에만 필요한 것이 아니라면, 공통 서비스 (UserBookTagService
)로 분리하는 것이 가장 좋은 방법!
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);
}
}
}
}
}
}
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);
...
}
}
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);
...
}
}
BookShelfService
에서 직접 호출 (비추천)BookShelfService
와 ArticleCreateService
가 서로 강하게 묶여 있어 유지보수가 어려움 UserBookTagService
를 만들어 분리 (추천!)updateUserBookTag
는 BookShelfService
와 ArticleCreateService
에서 모두 사용하므로, 공통 기능을 UserBookTagService
로 분리 📌 이렇게 분리하면 유지보수성이 높아지고 확장성이 좋아진다! 🚀