오늘 팀에서 흥미로운 논의가 있었다. "중복되는 코드를 어떻게 처리할 것인가?" 에 대한 주제였는데, 생각보다 의견이 갈렸다.
문제 상황
프로젝트에서 여러 Service 클래스에서 getUserById()를 사용할 때, orElseThrow()로 예외를 던지는 부분이 통일되지 않았다.
// 어떤 곳에서는
userRepository.findById(id)
.orElseThrow(() -> throw new BusinessException(ErrorCode.UNAUTHORIZE);
// 다른 곳에서는
userRepository.findById(id)
.orElseThrow(() -> throw new BusinessException(ErrorCode.NOT_FOUND);
GlobalException은 만들어져 있지만, 같은 상황(유저를 찾지 못함)에서 던지는 예외가 제각각이었다.
제안된 해결책
UserUtilService 생성
@Component
public class UserValidator {
private final UserRepository userRepository;
public User getByIdOrThrow(Long id) {
return userRepository.findById(id)
.orElseThrow(() -> throw new BusinessException(ErrorCode.NOT_FOUND);
}
}
이렇게 하면 유저 조회 + 예외 처리를 한 곳에서 통일할 수 있다.
찬성 vs 반대 의견
찬성 측 의견:
- 예외 처리의 일관성 확보
- 도메인 규칙을 코드로 명시화
- 나중에 로깅이나 추가 검증 로직이 생기면 한 곳만 수정하면 됨
반대 측 의견:
- UserService와 UserUtilService(또는 UserValidator)를 동시에 주입받아야 해서 의존성이 늘어남
- 지금은 크게 조회하는 부분에서만 이런 현상이 발생함
- 단순한 조회 기능을 위해 별도 클래스를 만드는 게 오버 엔지니어링 아닌가?
- 구체적인 대안은 제시되지 않았음
내 생각 정리
처음에는 "오버 엔지니어링일 수도 있겠다"고 생각했지만, 곰곰이 생각해보니 이건 오버 엔지니어링이 아니라 필요한 리팩토링이라는 결론에 도달했다.
오버 엔지니어링과 좋은 설계의 차이:
- 오버 엔지니어링: 필요하기는 하지만 너무 과한 설계
- 좋은 설계: 지금 당장 발생하고 있는 문제(예외 불일치)를 해결하는 것
의존성 증가에 대한 반박:
- 오히려 역할이 명확해져서 UserService가 가벼워질 수 있음
- 단일 책임 원칙(SRP)에 부합: 검증은 Validator가, 비즈니스 로직은 Service가
- 작은 유틸 클래스 하나 추가하는 비용 < 예외 처리 불일치로 인한 혼란
결론
팀 프로젝트에서는 일관성이 정말 중요하다. 같은 상황에서 다른 예외를 던지면 API를 사용하는 프론트엔드 개발자나 다른 팀원들이 혼란스러워한다고 생각한다.
"코드 중복을 줄이자"는 단순히 타이핑을 줄이는 게 아니라, 비즈니스 규칙을 한 곳에서 관리하고 일관성을 유지하자는 의미다. 이런 관점에서 보면 UserUtilService를 만드는 것은 충분히 가치 있는 설계 결정이라고 생각한다.
다만 너무 많은 기능을 넣어서 UserService2가 되지 않도록 주의해야겠다. 단순 조회/검증 정도만 담당하고, 실제 비즈니스 로직은 UserService에 남겨두는 게 좋을 것 같다.
🎯 느낀 점
오늘 팀 논의를 통해 "좋은 코드란 무엇인가?"에 대해 깊이 생각해볼 수 있었다. 코드 중복을 무조건 제거하는 것도, 무조건 남겨두는 것도 답이 아니다.
지금 우리 팀이 겪고 있는 실제 문제가 무엇인지 파악하고, 그에 맞는 적절한 수준의 해결책을 찾는 것이 중요하다는 걸 배웠다.
내일은 오늘 논의한 내용을 바탕으로 실제로 코드를 작성해보면서 더 구체적으로 고민해봐야겠다.
'👍코드 회고' 카테고리의 다른 글
| Saga 패턴 (0) | 2025.11.25 |
|---|---|
| N+1 (10.17) (0) | 2025.10.17 |
| 장바구니 코드 속 store_id는 어디에 둘까? (10.15) (0) | 2025.10.15 |
| 서비스단 깔끔하게 하기 (10.02) (0) | 2025.10.03 |
| 스프링 개발 회고 (10.01) (0) | 2025.10.01 |