DeepSeek 활용한 레거시 코드 리팩토링 검증

AI 기반 코드 리뷰 도구를 활용하여 복잡한 비즈니스 로직을 담은 레거시 메서드를 리팩토링한 후, 기능적 동등성과 코드 품질을 검증하는 방법을 살펴봅니다.

검증용 프롬프트 설계

DeepSeek에 코드 비교 분석을 요청할 때 사용하는 프롬프트 구조입니다. 명확한 지시와 함께 리팩토링 전후 코드를 제시합니다:

다음 코드 리팩토링의 품질과 기존 기능 충족 여부를 검토해주세요:

[리팩토링 후 코드]
...

[리팩토링 전 코드]
...

사례: 데이터 권한 조회 로직 개선

개선된 구조 (After)

@Override
public RoleDataVo fetchPermissionData(Integer menuId, Long brandDeptId) {
    PermissionContext ctx = new PermissionContext(menuId, brandDeptId);
    
    switch (ctx.resolveUserCategory()) {
        case BRAND_OWNER -> ctx.setupBrandOwner();
        case BRAND_EMPLOYEE -> ctx.setupBrandEmployee(orderDao, shopDao);
        case FRANCHISE_OWNER -> ctx.setupFranchiseOwner();
        case FRANCHISE_EMPLOYEE -> ctx.setupFranchiseEmployee(orderDao, bizDao, staffDao);
        case null, default -> ctx.setupFallback();
    }
    
    ctx.finalizeSetup(bizDao);
    return ctx.extractResult();
}

컨텍스트 클래스 핵심 구조

@Data
public class PermissionContext {
    private final RoleDataVo result = new RoleDataVo();
    private final SysUser currentUser = AuthUtil.getCurrentUser();
    private final List<String> userRoles = new ArrayList<>(AuthUtil.getRoleCodes());
    
    private List<Long> departmentIds = new ArrayList<>();
    private Set<Long> accessibleBizIds = new HashSet<>(128);
    private Set<Long> deptBizScope = new HashSet<>(128);
    
    private boolean maskingRequired = true;
    private long dataTimeWindow = 1L;
    private boolean hasDeptConstraint = false;
    
    // 생성자 및 타입별 초기화 메서드들...
}

기존 구조 (Before)

@Override
public RoleDataVo fetchPermissionData(Integer menuId, Long brandDeptId) {
    RoleDataVo result = new RoleDataVo();
    SysUser user = AuthUtil.getCurrentUser();
    List<String> roleCodes = new ArrayList<>(AuthUtil.getRoleCodes());
    List<Long> deptIds = new ArrayList<>();
    Set<Long> bizScope = new HashSet<>(128);
    Set<Long> deptBizScope = new HashSet<>(128);
    boolean needMasking = true;
    long timeWindow = 1L;

    // 사용자 유형별 거대한 switch 블록 (150+ 라인)
    switch (user.getUserType()) {
        case 1: // 브랜드 소유자
            timeWindow = -1;
            deptIds = null;
            bizScope = null;
            needMasking = false;
            result.setBrandId(user.getBrandId());
            result.setAdminFlag(true);
            break;
        case 4: // 브랜드 직원
            // 40+ 라인의 중첩 조건 로직...
            break;
        // ... 기타 케이스
    }
    // 공통 후처리 로직...
    return result;
}

AI 검증 결과 분석

품질 향상 지표

항목개선 내용
응집도단일 책임 원칙 적용, 컨텍스트 클래스로 상태 관리 중앙화
가독성메인 메서드 20라인으로 축소, 의도 드러내는 네이밍
확장성신규 사용자 유형 추가 시 case 분기만 확장
중복 제거공통 규칙 처리를 별도 메서드로 추출

발견된 결함 사례

AI 검증 과정에서 식별된 논리 오류:

// 문제 코드
public boolean missingRoles() {
    return CollUtil.isNotEmpty(this.userRoles); // 부정 조건 오류
}

// 수정 필요
public boolean hasAssignedRoles() {
    return CollUtil.isNotEmpty(this.userRoles);
}
// 또는
public boolean noRolesAssigned() {
    return CollUtil.isEmpty(this.userRoles);
}

검증 체크리스트 자동화

AI에게 요청할 수 있는 구체적인 검증 항목:

  1. 동등성 검증: 모든 분기 조건이 동일하게 처리되는지 확인
  2. 누락 검출: 리팩토링 과정에서 삭제된 로직 별
  3. 사이드 이펙트: 전역 상태 변경 여부 확인
  4. 예외 처리: 기존의 방어적 코드가 유지되는지 검사

실무 적용 팁

효과적인 AI 활용을 위한 추가 전략:

  • 점진적 검증: 한 번에 전체가 아닌 사용자 유형별로 분할 검증
  • 테스트 케이스 생성: AI가 각 분기의 입력-출력 쌍을 제안하도록 요청
  • 회귀 방지: "기존 코드의 어떤 동작이 변경되었는지"를 명시적으로 질문

한계와 보완

AI 검증의 한계를 인지하고 다음을 병행해야 합니다:

  • 단위 테스트로 핵심 경로 커버리지 확보
  • 통합 테스트로 실제 데이터 흐름 검증
  • 코드 리뷰로 AI가 놓친 비즈니스 규칙 확인

태그: DeepSeek Code Refactoring java Legacy Code Code Review

6월 25일 18:22에 게시됨