소프트웨어 개발에서 리팩토링은 단순히 코드를 정리하는 것 이상의 의미를 갖습니다. 그것은 시스템의 구조를 개선하고, 미래의 변화에 대비하며, 팀의 생산성을 높이는 중요한 과정입니다. 최근 여러 엔티티의 로그를 관리하는 서비스들을 개발하면서 코드 중복과 유지보수의 어려움이라는 도전에 직면했습니다. 이 글에서는 이러한 문제를 해결하기 위해 선택한 공통 인터페이스 도입 전략과 그 과정에서 얻은 인사이트를 공유하고자 합니다.
프로젝트 초기, 각 엔티티별로 독립적인 로그 관리 서비스를 구현했습니다. 예를 들어:
@Service
public class ContractLogService {
public void logCreation(Contract contract, String userId) {
// 계약 생성 로그 기록 로직
}
// 기타 메서드...
}
@Service
public class BusinessLogService {
public void logCreation(Business business, String userId) {
// 비즈니스 생성 로그 기록 로직
}
// 기타 메서드...
}
문제 해결의 핵심은 모든 로그 서비스가 공유할 수 있는 인터페이스를 설계하는 것이었습니다.
public interface LogService<T, D> {
List<D> getLogsById(Long id);
void logOperation(T oldEntity, T newEntity, String userId, String operationType);
void logCreation(T newEntity, String userId);
void logUpdate(T oldEntity, T updatedEntity, String userId);
void logDeletion(T deletedEntity, String userId);
}
이 인터페이스는 제네릭을 활용하여 다양한 엔티티 타입(T
)과 DTO 타입(D
)에 대응할 수 있도록 설계되었습니다.
인터페이스만으로는 중복 코드를 완전히 제거하기 어려웠기 때문에, 공통 로직을 담은 추상 클래스를 추가로 도입했습니다.
public abstract class AbstractLogService<T, D> implements LogService<T, D> {
@Override
public void logOperation(T oldEntity, T newEntity, String userId, String operationType) {
// 공통 로그 기록 로직
}
protected abstract String getEntityType();
protected abstract Long getEntityId(T entity);
// 기타 공통 메서드...
}
각 엔티티별 로그 서비스는 AbstractLogService
를 상속받아 구현했습니다.
@Service
@RequiredArgsConstructor
public class ContractLogServiceImpl extends AbstractLogService<Contract, ContractLogDTO> {
private final ContractLogRepository logRepository;
@Override
protected String getEntityType() {
return "Contract";
}
@Override
protected Long getEntityId(Contract contract) {
return contract.getId();
}
// 엔티티 특화 로직 구현...
}
리팩토링 과정에서 몇 가지 도전에 직면했습니다:
기존 코드와의 호환성: 리팩토링된 구조를 기존 시스템에 통합하는 과정에서 일시적인 호환성 문제가 발생했습니다. 이를 해결하기 위해 점진적인 마이그레이션 전략을 수립했습니다.
성능 최적화: 공통 인터페이스 도입 초기에는 약간의 성능 저하가 관찰되었습니다. 이는 추상화 레이어로 인한 것이었으며, 프로파일링을 통해 핫스팟을 식별하고 최적화하여 해결했습니다.
이번 리팩토링을 통해 단순히 코드를 개선하는 것을 넘어, 더 유연하고 확장 가능한 시스템 아키텍처를 구축했습니다. 이는 미래의 요구사항 변화에 더 빠르게 대응할 수 있는 기반이 되었습니다.
향후 계획:
1. 다른 도메인으로의 확장: 이번에 얻은 인사이트를 바탕으로 다른 도메인의 서비스들도 유사한 방식으로 리팩토링할 예정입니다.
2. 지속적인 개선: 정기적인 코드 리뷰와 리팩토링 세션을 통해 시스템의 품질을 계속해서 향상시켜 나갈 것입니다.
3. 문서화 강화: 이번 경험을 바탕으로 아키텍처 결정 사항과 설계 원칙을 문서화하여 팀의 지식 자산으로 활용할 계획입니다.