-
Notifications
You must be signed in to change notification settings - Fork 7
Open
Description
CompositeService 추가를 통한 Service 레이어 설계 개선
description
알트가 제안한 레이어 개선안 중 서비스 레이어 관련하여 정리하여 이슈로 올립니다.
현재 상황
Taggle의 레이어 구조 변천사는 아래와 같습니다.
- Base Entity 기반 Service & Repository 만 존재합니다.
- 어떤 Base Service가 다른 Service 를 참조 해야하는 경우가 생겨 다른 Base Service를 직접 참조하기 시작
- 서로 참조하는 Service 들이 생기면서 순환참조 발생
- 순환 참조문제가 있는 Service들에 한해 Service 가 참조하던 다른 Base Service 대신 Base Repository를 직접 참조하여 순환 참조 문제 제거
- 다른 Base Service 를 참조하는 Service와 다른 Base Repository를 참조하는 Service 가 혼재
최종적인 상황에 대한 코드는 아래와 같습니다.
public class AService {
// base repository
private final ARepository aRepository;
// A와 B Service 각각 상대 Service 를 참조하면 순환참조 발생하기 때문에 Repository참조
private final BRepository bRepository;
// 다른 서비스 직접 참조
private final CService cService;
...
}
public class BService {
// base repository
private final BRepository bRepository;
// A와 B Service 각각 상대 Service 를 참조하면 순환참조 발생하기 때문에 Repository참조
private final ARepository aRepository;
...
}
public class CService {
// base repository
private final CRepository cRepository;
...
}문제점
- 코드의 중복
- 같은 Base Repository를 참조하는 Service 들에서 코드 로직 중복이 발생합니다.
e.g. findTagByTagIdAndUserId()
-> 단건 조회시 Optional.orElse(Throw) 처리로 인해 메서드 분리가 필요하다.
-> 이 로직이 각 서비스에 흩어져 변화의 여파가 퍼진다. (e.g. 예외처리 문구 수정)
- 일관성이 없다.
- 기본적으로 Base Service는 다른 Base Service를 참조하다가, 순환 참조 가능성이 있는 Service를 참조하는 경우에는 해당 Base Repository를 참조 하고 있습니다. 결과적으로, 어떤 곳에서는 Service, 어떤 곳에서는 Repository를 참조하는 곳이 생겨 코드에 일관성이 없어졌습니다.
- Service의 무용?
- 또한 Repository를 포함한 해당 도메인 에 대한 기능을 추상화 시킨 것이 Service인데, A Base Service에서 B Repository를 참조함으로서, BService를 만든 의미 또한 퇴색되어 보입니다.
제안
이러한 문제가 생겼던 근본적인 원인은 Base Service가 Base Service가 아니었기 때문입니다.
- Repository와 가장 근접한 Base Service는 해당 Repository의 CRUD만 수행하도록 만든다.
- 여러 BaseService의 의존이 필요한 경우, Base Service들을 참조하는 Composite Service를 만든다.
코드 참조
public class AService {
private final ARepository aRepository;
...
}
public class BService {
private final BRepository bRepository;
...
}
public class CService {
private final CRepository cRepository;
...
}
public class ABService {
private final AService aService;
private final BService bService;
...
}
public class ACService {
private final AService aService;
private final CService cService;
...
}다음과 같이 설계하는 경우,
- Base Service끼리는 다른 Base Service 변화에 영향을 받지 않습니다.
- Base Service는 Base Repository를, Composite Service는 Base Service를 참조하는 일관적인 구조를 가져갈 수 있습니다.
- 더불어서 순환참조의 문제를 피할 수 있습니다.
- 중복 문제를 제거할 수 있습니다. (위에서 제시한 문제 참조)
고려해볼만한 점.
- composite Service의 적절한 패키지 위치.
- 기타 추가적인 내용들은 같이 논의해보면 좋을 것 같습니다.
progress
- Service Layer 함께 논의 후, 재 설계
Reactions are currently unavailable