리팩토링 vs 오버 엔지니어링 (10.16)
2025. 10. 16. 22:08

오늘 팀에서 흥미로운 논의가 있었다. "중복되는 코드를 어떻게 처리할 것인가?" 에 대한 주제였는데, 생각보다 의견이 갈렸다.

문제 상황

프로젝트에서 여러 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가
  • 작은 유틸 클래스 하나 추가하는 비용 < 예외 처리 불일치로 인한 혼란
  1.  

결론

팀 프로젝트에서는 일관성이 정말 중요하다. 같은 상황에서 다른 예외를 던지면 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