code-refactoring
Refactors complex codebases by applying clean code principles and design patterns.
Install
mkdir -p .claude/skills/code-refactoring-themystic07 && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/15621" && unzip -o skill.zip -d .claude/skills/code-refactoring-themystic07 && rm skill.zipInstalls to .claude/skills/code-refactoring-themystic07
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Simplify and refactor code while preserving behavior, improving clarity, and reducing complexity. Use when simplifying complex code, removing duplication, or applying design patterns. Handles Extract Method, DRY principle, SOLID principles, behavior validation, and refactoring patterns.Key capabilities
- →Extract methods from long functions
- →Remove duplicate code by extracting common logic
- →Replace conditional logic with polymorphism
- →Validate behavior after refactoring using tests
- →Document changes made during refactoring
- →Apply SOLID principles and design patterns
How it works
This skill refactors code by applying techniques like method extraction, duplication removal, and polymorphism, ensuring behavior preservation through validation steps and documenting all changes.
Inputs & outputs
When to use code-refactoring
- →Removing duplicate code (DRY)
- →Extracting long methods
- →Applying SOLID principles
- →Simplifying complex functions
About this skill
Code Refactoring
When to use this skill
- 코드 리뷰: 복잡하거나 중복된 코드 발견
- 새 기능 추가 전: 기존 코드 정리
- 버그 수정 후: 근본 원인 제거
- 기술 부채 해소: 정기적인 리팩토링
Instructions
Step 1: Extract Method (메서드 추출)
Before (긴 함수):
function processOrder(order: Order) {
// 검증
if (!order.items || order.items.length === 0) {
throw new Error('Order must have items');
}
if (!order.customerId) {
throw new Error('Order must have customer');
}
// 가격 계산
let total = 0;
for (const item of order.items) {
total += item.price * item.quantity;
}
const tax = total * 0.1;
const shipping = total > 100 ? 0 : 10;
const finalTotal = total + tax + shipping;
// 재고 확인
for (const item of order.items) {
const product = await db.product.findUnique({ where: { id: item.productId } });
if (product.stock < item.quantity) {
throw new Error(`Insufficient stock for ${product.name}`);
}
}
// 주문 생성
const newOrder = await db.order.create({
data: {
customerId: order.customerId,
items: order.items,
total: finalTotal,
status: 'pending'
}
});
return newOrder;
}
After (메서드 추출):
async function processOrder(order: Order) {
validateOrder(order);
const total = calculateTotal(order);
await checkInventory(order);
return await createOrder(order, total);
}
function validateOrder(order: Order) {
if (!order.items || order.items.length === 0) {
throw new Error('Order must have items');
}
if (!order.customerId) {
throw new Error('Order must have customer');
}
}
function calculateTotal(order: Order): number {
const subtotal = order.items.reduce((sum, item) => sum + item.price * item.quantity, 0);
const tax = subtotal * 0.1;
const shipping = subtotal > 100 ? 0 : 10;
return subtotal + tax + shipping;
}
async function checkInventory(order: Order) {
for (const item of order.items) {
const product = await db.product.findUnique({ where: { id: item.productId } });
if (product.stock < item.quantity) {
throw new Error(`Insufficient stock for ${product.name}`);
}
}
}
async function createOrder(order: Order, total: number) {
return await db.order.create({
data: {
customerId: order.customerId,
items: order.items,
total,
status: 'pending'
}
});
}
Step 2: Remove Duplication (중복 제거)
Before (중복):
async function getActiveUsers() {
return await db.user.findMany({
where: { status: 'active', deletedAt: null },
select: { id: true, name: true, email: true }
});
}
async function getActivePremiumUsers() {
return await db.user.findMany({
where: { status: 'active', deletedAt: null, plan: 'premium' },
select: { id: true, name: true, email: true }
});
}
After (공통 로직 추출):
type UserFilter = {
plan?: string;
};
async function getActiveUsers(filter: UserFilter = {}) {
return await db.user.findMany({
where: {
status: 'active',
deletedAt: null,
...filter
},
select: { id: true, name: true, email: true }
});
}
// 사용
const allActiveUsers = await getActiveUsers();
const premiumUsers = await getActiveUsers({ plan: 'premium' });
Step 3: Replace Conditional with Polymorphism
Before (긴 if-else):
class PaymentProcessor {
process(payment: Payment) {
if (payment.method === 'credit_card') {
// 신용카드 처리
const cardToken = this.tokenizeCard(payment.card);
const charge = this.chargeCreditCard(cardToken, payment.amount);
return charge;
} else if (payment.method === 'paypal') {
// PayPal 처리
const paypalOrder = this.createPayPalOrder(payment.amount);
const approval = this.getPayPalApproval(paypalOrder);
return approval;
} else if (payment.method === 'bank_transfer') {
// 은행 이체 처리
const transfer = this.initiateBankTransfer(payment.account, payment.amount);
return transfer;
}
}
}
After (다형성):
interface PaymentMethod {
process(payment: Payment): Promise<PaymentResult>;
}
class CreditCardPayment implements PaymentMethod {
async process(payment: Payment): Promise<PaymentResult> {
const cardToken = await this.tokenizeCard(payment.card);
return await this.chargeCreditCard(cardToken, payment.amount);
}
}
class PayPalPayment implements PaymentMethod {
async process(payment: Payment): Promise<PaymentResult> {
const order = await this.createPayPalOrder(payment.amount);
return await this.getPayPalApproval(order);
}
}
class BankTransferPayment implements PaymentMethod {
async process(payment: Payment): Promise<PaymentResult> {
return await this.initiateBankTransfer(payment.account, payment.amount);
}
}
class PaymentProcessor {
private methods: Map<string, PaymentMethod> = new Map([
['credit_card', new CreditCardPayment()],
['paypal', new PayPalPayment()],
['bank_transfer', new BankTransferPayment()]
]);
async process(payment: Payment): Promise<PaymentResult> {
const method = this.methods.get(payment.method);
if (!method) {
throw new Error(`Unknown payment method: ${payment.method}`);
}
return await method.process(payment);
}
}
Step 4: Introduce Parameter Object
Before (많은 파라미터):
function createUser(
name: string,
email: string,
password: string,
age: number,
country: string,
city: string,
postalCode: string,
phoneNumber: string
) {
// ...
}
After (객체로 그룹화):
interface UserProfile {
name: string;
email: string;
password: string;
age: number;
}
interface Address {
country: string;
city: string;
postalCode: string;
}
interface CreateUserParams {
profile: UserProfile;
address: Address;
phoneNumber: string;
}
function createUser(params: CreateUserParams) {
const { profile, address, phoneNumber } = params;
// ...
}
// 사용
createUser({
profile: { name: 'John', email: '[email protected]', password: 'xxx', age: 30 },
address: { country: 'US', city: 'NYC', postalCode: '10001' },
phoneNumber: '+1234567890'
});
Step 5: SOLID 원칙 적용
Single Responsibility (단일 책임):
// ❌ 나쁜 예: 여러 책임
class User {
constructor(public name: string, public email: string) {}
save() {
// DB 저장
}
sendEmail(subject: string, body: string) {
// 이메일 발송
}
generateReport() {
// 리포트 생성
}
}
// ✅ 좋은 예: 책임 분리
class User {
constructor(public name: string, public email: string) {}
}
class UserRepository {
save(user: User) {
// DB 저장
}
}
class EmailService {
send(to: string, subject: string, body: string) {
// 이메일 발송
}
}
class UserReportGenerator {
generate(user: User) {
// 리포트 생성
}
}
Output format
리팩토링 체크리스트
- [ ] 함수는 한 가지 일만 한다 (SRP)
- [ ] 함수 이름이 하는 일을 명확히 설명한다
- [ ] 함수는 20줄 이하 (가이드라인)
- [ ] 매개변수는 3개 이하
- [ ] 중복 코드 없음 (DRY)
- [ ] if 중첩은 2단계 이하
- [ ] 매직 넘버 없음 (상수로 추출)
- [ ] 주석 없이도 이해 가능 (자기 문서화)
Constraints
필수 규칙 (MUST)
- 테스트 먼저: 리팩토링 전 테스트 작성
- 작은 단계: 한 번에 하나씩 변경
- 동작 보존: 기능 변경 없음
금지 사항 (MUST NOT)
- 동시에 여러 작업: 리팩토링 + 기능 추가 동시 금지
- 테스트 없이 리팩토링: 회귀 위험
Best practices
- Boy Scout Rule: 코드를 발견했을 때보다 깨끗하게
- 리팩토링 타이밍: Red-Green-Refactor (TDD)
- 점진적 개선: 완벽보다 꾸준히
- 행동 보존: 리팩토링은 기능 변경 없음
- 작은 커밋: 포커스된 단위로 커밋
Behavior Validation (Code Simplifier Integration)
Step A: Understand Current Behavior
리팩토링 전 현재 동작 완전히 이해:
## Behavior Analysis
### Inputs
- [입력 파라미터 목록]
- [타입 및 제약사항]
### Outputs
- [반환값]
- [부수 효과 (side effects)]
### Invariants
- [항상 참이어야 하는 조건들]
- [경계 조건 (edge cases)]
### Dependencies
- [외부 의존성]
- [상태 의존성]
Step B: Validate After Refactoring
# 1. 테스트 실행
npm test -- --coverage
# 2. 타입 체크
npx tsc --noEmit
# 3. 린트 확인
npm run lint
# 4. 이전 동작과 비교 (스냅샷 테스트)
npm test -- --updateSnapshot
Step C: Document Changes
## Refactoring Summary
### Changes Made
1. [변경 1]: [이유]
2. [변경 2]: [이유]
### Behavior Preserved
- [x] 동일한 입력 → 동일한 출력
- [x] 부수 효과 동일
- [x] 에러 처리 동일
### Risks & Follow-ups
- [잠재적 위험]
- [후속 작업]
### Test Status
- [ ] Unit tests: passing
- [ ] Integration tests: passing
- [ ] E2E tests: passing
Troubleshooting
Issue: Tests fail after refactor
Cause: 동작 변경이 발생함 Solution: 되돌리고 변경을 격리하여 재시도
Issue: Code still complex
Cause: 하나의 함수에 여러 책임 혼합 Solution: 명확한 경계로 더 작은 단위 추출
Issue: Performance regression
Cause: 비효율적인 추상화 도입 Solution: 프로파일링 후 핫 패스 최적화
Multi-Agent Workflow
Validation & Retrospectives
- Round 1 (Orchestrator): 행동 보존 체크리스트 검증
- Round 2 (Analyst): 복잡도 및 중복 분석
- Round 3 (Executor): 테스트 또는 정적 분석 검증
Agent Roles
| Agent | Role |
|---|---|
| Claude | 리팩토링 계획, 코드 변환 |
| Gemini | 대규모 코드베이스 분석, 패턴 탐지 |
| Codex | 테스트 실행, 빌드 검증 |
Workflow Example
# 1. Gemini: 코드베이스 분석
ask-gemini "@src/ 복잡도 높은 함수 목록 추출"
# 2. Claude: 리팩토링 계획 및 실행
# IMPLEMENTATION_PLAN.md 기반 작업
# 3. Codex: 검증
codex-cli shell "npm test && npm run lint"
References
Metadata
버전
- 현재 버전: 1.0.0
- 최종 업데이트: 2025-01-01
- 호환 플랫폼: Claude, ChatGPT, Gemini
관련 스킬
태그
#refactoring #code-quality #DRY #SOLID #design-patterns #clean-code
Examples
Example 1: Basic usage
<!-- Add example content here -->Example 2: Advanced usage
<!-- Add advanced example content here -->When not to use it
- →When the primary goal is to add new features without code improvement
- →When behavior changes are intended, rather than preservation
- →When tests are not available to validate behavior preservation
Limitations
- →Refactoring must preserve existing behavior
- →Changes must be validated by running tests, type checks, and linters
- →Documentation of changes is required after refactoring
How it compares
This skill provides a structured, step-by-step approach to refactoring, including explicit validation and documentation, which is more systematic than ad-hoc code improvements.
Compared to similar skills
code-refactoring side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| code-refactoring (this skill) | 0 | 5mo | Review | Intermediate |
| typescript-review | 39 | 2mo | No flags | Intermediate |
| react-modernization | 21 | 2mo | No flags | Advanced |
| antfu | 6 | 3mo | Review | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
More by TheMystic07
View all by TheMystic07 →You might also like
typescript-review
metabase
Review TypeScript and JavaScript code changes for compliance with Metabase coding standards, style violations, and code quality issues. Use when reviewing pull requests or diffs containing TypeScript/JavaScript code.
react-modernization
wshobson
Upgrade React applications to latest versions, migrate from class components to hooks, and adopt concurrent features. Use when modernizing React codebases, migrating to React Hooks, or upgrading to latest React versions.
antfu
antfu
Anthony Fu's opinionated tooling and conventions for JavaScript/TypeScript projects. Use when setting up new projects, configuring ESLint/Prettier alternatives, monorepos, library publishing, or when the user mentions Anthony Fu's preferences.
tdd-workflow
affaan-m
在编写新功能、修复错误或重构代码时使用此技能。强制执行测试驱动开发,包含单元测试、集成测试和端到端测试,覆盖率超过80%。
typescript-expert
davila7
TypeScript and JavaScript expert with deep knowledge of type-level programming, performance optimization, monorepo management, migration strategies, and modern tooling. Use PROACTIVELY for any TypeScript/JavaScript issues including complex type gymnastics, build performance, debugging, and architectural decisions. If a specialized expert is a better fit, I will recommend switching and stop.
ast-grep-find
parcadei
AST-based code search and refactoring via ast-grep MCP