Receber por email
← Voltar para o catálogo

code-refactoring

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.

367estrelas
Atualizado há 4 meses

Ver no GitHub ↗

Como adicionar

/plugin marketplace add aiskillstore/marketplace

O comando exato pode variar conforme o repositório. Confira o README no GitHub.

Para o autor da skill

Cole no README do seu repo

Mostra que sua skill está catalogada na Skillteca, gera backlink e tráfego rastreável.

[![Skillteca](https://www.skillteca.com.br/api/badge/code-refactoring/svg)](https://www.skillteca.com.br/skills/code-refactoring)

Skills relacionadas

Ver todas de Segurança →

Alerta por categoria

Receba novas skills de Segurança toda segunda

1 email curto, só com as skills novas de Segurança. 4 minutos de leitura, sem spam, cancela com 1 clique.

Você confirma o email no primeiro envio. Sem spam. Cancela com 1 clique.

Ler descrição completa

Code Refactoring

When to use this skill

  • Code review: Discovering complex or duplicated code
  • Before adding new features: Cleaning up existing code
  • After bug fixes: Removing root causes
  • Resolving technical debt: Regular refactoring

Instructions

Step 1: Extract Method

Before (long function):

function processOrder(order: Order) {
  // Validation
  if (!order.items || order.items.length === 0) {
    throw new Error('Order must have items');
  }
  if (!order.customerId) {
    throw new Error('Order must have customer');
  }

  // Price calculation
  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;

  // Inventory check
  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}`);
    }
  }

  // Create order
  const newOrder = await db.order.create({
    data: {
      customerId: order.customerId,
      items: order.items,
      total: finalTotal,
      status: 'pending'
    }
  });

  return newOrder;
}

After (method extraction):

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 (duplication):

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 (extract common logic):

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 }
  });
}

// Usage
const allActiveUsers = await getActiveUsers();
const premiumUsers = await getActiveUsers({ plan: 'premium' });

Step 3: Replace Conditional with Polymorphism

Before (long if-else):

class PaymentProcessor {
  process(payment: Payment) {
    if (payment.method === 'credit_card') {
      // Credit card processing
      const cardToken = this.tokenizeCard(payment.card);
      const charge = this.chargeCreditCard(cardToken, payment.amount);
      return charge;
    } else if (payment.method === 'paypal') {
      // PayPal processing
      const paypalOrder = this.createPayPalOrder(payment.amount);
      const approval = this.getPayPalApproval(paypalOrder);
      return approval;
    } else if (payment.method === 'bank_transfer') {
      // Bank transfer processing
      const transfer = this.initiateBankTransfer(payment.account, payment.amount);
      return transfer;
    }
  }
}

After (polymorphism):

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 (many parameters):

function createUser(
  name: string,
  email: string,
  password: string,
  age: number,
  country: string,
  city: string,
  postalCode: string,
  phoneNumber: string
) {
  // ...
}

After (grouped into object):

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;
  // ...
}

// Usage
createUser({
  profile: { name: 'John', email: 'john@example.com', password: 'xxx', age: 30 },
  address: { country: 'US', city: 'NYC', postalCode: '10001' },
  phoneNumber: '+1234567890'
});

Step 5: Apply SOLID Principles

Single Responsibility:

// ❌ Bad example: multiple responsibilities
class User {
  constructor(public name: string, public email: string) {}

  save() {
    // Save to DB
  }

  sendEmail(subject: string, body: string) {
    // Send email
  }

  generateReport() {
    // Generate report
  }
}

// ✅ Good example: separated responsibilities
class User {
  constructor(public name: string, public email: string) {}
}

class UserRepository {
  save(user: User) {
    // Save to DB
  }
}

class EmailService {
  send(to: string, subject: string, body: string) {
    // Send email
  }
}

class UserReportGenerator {
  generate(user: User) {
    // Generate report
  }
}

Output format

Refactoring Checklist

- [ ] Function does one thing only (SRP)
- [ ] Function name clearly describes what it does
- [ ] Function is 20 lines or fewer (guideline)
- [ ] 3 or fewer parameters
- [ ] No duplicate code (DRY)
- [ ] if nesting is 2 levels or fewer
- [ ] No magic numbers (extract as constants)
- [ ] Understandable without comments (self-documenting)

Constraints

Mandatory Rules (MUST)

  1. Test first: Write tests before refactoring
  2. Small steps: Change one thing at a time
  3. Behavior preservation: No functional changes

Prohibited (MUST NOT)

  1. Multiple tasks simultaneously: No refactoring + feature addition at the same time
  2. Refactoring without tests: Risk of regression

Best practices

  1. Boy Scout Rule: Leave code cleaner than you found it
  2. Refactoring timing: Red-Gree
Compartilhar X LinkedIn