본문으로 건너뛰기
cccskills
무료GitHub에 공개

lift-up-conditional

여러 메서드·분기에 중복된 동일 조건문을 상위(호출자 또는 메서드 시작)로 끌어올려 중복 제거. "조건 위로 올려", "같은 if가 여러 메서드에", "lift up", "/lift-up-conditional" 요청 시 사용. 단, 한 메서드 안에서 동일 결과를 내는 조건문 통합은 /consolidate-conditional이 적합. /lift-up-conditional [commit-ref]로 호출.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

설치 방법 보기

포함된 파일(1)

  • SKILL.md7.2 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

Lift Up Conditional Skill

여러 곳에 중복된 조건문을 상위로 끌어올려 중복을 제거하고 코드 의도를 명확히 한다.

GOAL

  • 성공 = 중복 조건문이 상위로 끌어올려져 커밋 완료됨
  • 동일한 조건문이 여러 메서드/블록에서 반복됨
  • 조건에 따라 다른 처리가 필요한 패턴 식별됨
  • 후보 보고 후 조건문 끌어올리기 적용 (Tidy 계열 — 승인 없이)
  • 모든 테스트 통과

CONSTRAINTS

  • 계열: Tidy — 후보 보고 후 승인 없이 적용 (../../references/refactoring-procedure.md §0·§3-A)

Hard Rules

  • 동작 변경 금지 — 구조 개선만 수행
  • 테스트 수정 금지 — 구조 변경이 테스트를 실패시키면 되돌리기
  • 커밋 단위 — 1파일 x 1기법 = 1커밋 (논리적으로 연결된 파일은 함께)
  • git add -A 금지 — 변경된 파일만 명시적으로 추가

적용 패턴

Lift Up Conditional 리팩토링 단계:

  1. 중복 조건문 식별

    • 동일한 조건식이 여러 곳에서 반복
    • 조건에 따라 다른 동작 수행
  2. 조건을 변수로 추출

    • 중복된 조건식을 boolean 변수로 추출
    • 의미 있는 변수명으로 조건 의도 명확히
  3. 조건을 메서드로 추출 (선택적)

    • 복잡한 조건은 별도 메서드로
    • 메서드명으로 조건의 비즈니스 의미 표현
  4. 조건을 상위로 끌어올림

    • Surround with if-else로 조건을 한 곳으로 모음
    • 조건 내부에서 각 메서드 호출
    • 불필요한 중간 변수 제거 (inline)

Before/After 예시

// Before: 동일 조건 중복
public class ProductService {
    public double calculatePrice(Product product) {
        if (product.isOnSale()) {
            return product.getPrice() * 0.9;  // 10% 할인
        }
        return product.getPrice();
    }
    
    public String formatLabel(Product product) {
        if (product.isOnSale()) {
            return "SALE: " + product.getName();
        }
        return product.getName();
    }
    
    public String getBadgeColor(Product product) {
        if (product.isOnSale()) {
            return "red";
        }
        return "blue";
    }
}

// After: 조건을 상위로 끌어올림
public class ProductService {
    public ProductDisplay createDisplay(Product product) {
        if (product.isOnSale()) {
            return createSaleDisplay(product);
        }
        return createNormalDisplay(product);
    }
    
    private ProductDisplay createSaleDisplay(Product product) {
        double price = product.getPrice() * 0.9;
        String label = "SALE: " + product.getName();
        String badgeColor = "red";
        return new ProductDisplay(price, label, badgeColor);
    }
    
    private ProductDisplay createNormalDisplay(Product product) {
        double price = product.getPrice();
        String label = product.getName();
        String badgeColor = "blue";
        return new ProductDisplay(price, label, badgeColor);
    }
}

단계별 리팩토링 과정

// Step 1: 조건을 변수로 추출
boolean isOnSale = product.isOnSale();
if (isOnSale) { ... }

// Step 2: 조건을 메서드로 추출 (복잡한 경우)
private boolean isEligibleForDiscount(Product product) {
    return product.isOnSale() && product.getPrice() > 1000;
}

// Step 3: Surround with if-else로 조건 끌어올림
if (isEligibleForDiscount(product)) {
    double price = calculateSalePrice(product);
    String label = formatSaleLabel(product);
    String badge = getSaleBadgeColor();
} else {
    double price = calculateNormalPrice(product);
    String label = formatNormalLabel(product);
    String badge = getNormalBadgeColor();
}

// Step 4: 각 분기를 메서드로 추출 + inline
if (isEligibleForDiscount(product)) {
    return createSaleDisplay(product);
}
return createNormalDisplay(product);

적용 기준

Lift Up Conditional을 적용해야 하는 경우:

  1. 조건 중복: 동일한 조건문이 2곳 이상에서 반복
  2. 논리적 연관: 중복된 조건들이 같은 비즈니스 규칙을 나타냄
  3. 일관성: 조건이 참/거짓일 때의 처리가 여러 곳에서 일관됨
  4. 복잡도: 조건이 복잡하여 의도가 불명확함
  5. 변경 빈도: 조건이 자주 변경되어 여러 곳 수정 필요

OUTPUT FORMAT

실행 절차

공통 골격(대상 파일 수집 → 후보 제시(계열별 승인 규칙) → 적용 → 테스트 → 커밋/되돌리기, 브랜치·PR이 필요한 조건)은 이 스킬 디렉터리 기준 ../../references/refactoring-procedure.md가 정본이다. 아래는 이 기법에 고유한 부분만 규정한다.

중복 조건문 후보 식별 (공통 절차 2단계)

대상 파일에서 다음 패턴을 찾는다:

  • 동일한 조건식이 2곳 이상에서 반복
  • 조건식이 같은 변수/메서드를 참조
  • 조건 분기에서 서로 다른 메서드 호출
  • 논리적으로 같은 비즈니스 규칙

후보 제시 예시 (공통 절차 3단계)

후보를 보고하고 즉시 적용한다(Tidy 계열 — 정본 §3-A):

## 리팩토링 후보 1: Lift Up Conditional

**파일**: ProductService.java
**중복 조건**: product.isOnSale()

**반복 위치** (3곳):
1. calculatePrice() 메서드
2. formatLabel() 메서드
3. getBadgeColor() 메서드

**현재 코드**:
[조건이 반복되는 메서드들]

**제안 변경**:
1. 조건을 변수로 추출: boolean isOnSale = product.isOnSale()
2. createDisplay() 메서드 생성
3. 조건을 상위로 끌어올림 (surround with if-else)
4. 각 분기를 메서드로 추출
   - createSaleDisplay(product)
   - createNormalDisplay(product)
5. ProductDisplay 객체로 결과 통합

→ 승인 없이 적용 (Tidy 계열)

조건문 끌어올리기 실행 (공통 절차 4단계)

확정된 리팩토링을 하나씩 수행:

  1. 조건을 변수로 추출
  2. 조건을 메서드로 추출 (복잡한 경우)
  3. Surround with if-else로 조건 끌어올림
  4. 각 분기를 메서드로 추출
  5. 불필요한 중간 변수 제거 (inline)

커밋 메시지 형식:

refactor: lift up conditional [조건 설명] in [클래스명]

결과 보고

사용자에게 보고:

  • 적용된 조건문 끌어올리기 목록

FAILURE CONDITIONS

공통 실패 조건(계열별 승인 규칙 위반, 테스트 실패 방치, 테스트 수정, 커밋 단위, git add -A, heredoc 한글 메시지)은 ../../references/refactoring-procedure.md에 있다. 아래는 이 기법에 고유한 것만.

  • 논리적으로 다른 조건을 동일하다고 판단 (조건식은 같아도 의미가 다를 수 있음)
  • 조건 평가 순서 변경으로 부수효과 발생 (short-circuit 주의)
  • 단순히 조건만 이동하고 메서드 추출 없음 (가독성 개선 부족)

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

동일한 결과를 내는 여러 조건문(OR 나열·중첩 AND)을 하나로 통합하고 의미 있는 boolean 메서드로 추출. "조건문 합쳐", "같은 결과 반환하는 if 정리", "중첩 if 평탄화", "/consolidate-conditional" 요청 시 사용. 단, 여러 메서드에 흩어진 동일 조건을 호출자 쪽으로 올리는 것은 /lift-up-conditional, 복잡한 조건식·분기를 메서드로 쪼개는 것은 /decompose-conditional이 적합. /consolidate-conditional [commit-ref]로 호출.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

msbaek/msbaek-claude-plugins82026년 10월 16일 업데이트

기능의 external behavior를 Cucumber 인수 테스트(주 검증층)로 구축 — .feature 실행으로 문서↔코드 드리프트를 구조적으로 차단, Four Layer(Steps→Protocol Driver→SUT), 태그 기반 가역 제외, 기존 JUnit 인수 테스트 이관. "인수 테스트 도입", "Gherkin을 실행 가능하게", "cucumber 셋업" 요청 시 사용. /cucumber-acceptance로 호출.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

msbaek/msbaek-claude-plugins82026년 10월 16일 업데이트

복잡한 if/then/else의 조건식과 각 분기를 의미 있는 메서드로 추출하여 가독성 향상. "조건문 분해", "if 가독성", "복잡한 조건식에 이름 붙여", "/decompose-conditional" 요청 시 사용. 단, 같은 결과를 내는 조건문들을 하나로 합치는 것은 /consolidate-conditional, 타입별 분기를 클래스로 바꾸는 것은 /replace-conditional-with-poly가 적합. /decompose-conditional [commit-ref]로 호출.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

msbaek/msbaek-claude-plugins82026년 10월 16일 업데이트

Primitive Obsession 제거 — 검증·연산이 따라다니는 primitive 필드(금액+통화, 이메일 문자열 등)를 도메인 개념을 담은 Value Object로 치환. "값 객체 도입", "primitive obsession", "Money 클래스로", "/discover-value-object" 요청 시 사용. 단, 함께 전달되는 파라미터 묶음을 객체로 바꾸는 것은 /introduce-parameter-object, 컬렉션을 감싸는 것은 /first-class-collection이 적합. /discover-value-object [commit-ref]로 호출.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

msbaek/msbaek-claude-plugins82026년 10월 16일 업데이트

컬렉션 getter가 내부 List/Set을 직접 노출하는 것을 방지 — unmodifiable 반환 + add/remove 메서드 제공. "컬렉션 캡슐화", "getter가 List 그대로 노출", "unmodifiable로", "/encapsulate-collection" 요청 시 사용. 단, 컬렉션과 관련 로직을 전용 클래스로 뽑는 것은 /first-class-collection이 적합. /encapsulate-collection [commit-ref]로 호출.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

msbaek/msbaek-claude-plugins82026년 10월 16일 업데이트

암묵적 의존성(전역 변수·클래스 필드·싱글턴 접근)을 명시적 파라미터로 전환하여 메서드 투명성 향상. "숨은 의존성 드러내", "필드 대신 파라미터로", "전역 참조 제거", "/explicit-parameters" 요청 시 사용. 단, 파라미터가 많아져 묶어야 하면 /introduce-parameter-object, I/O와 계산 분리는 /segregate-functional-core가 적합. /explicit-parameters [commit-ref]로 호출.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

msbaek/msbaek-claude-plugins82026년 10월 16일 업데이트

msbaek의 스킬 모두 보기

이 스킬의 문제 신고