Skip to main content

refactoring

Refactoring - Padrões e técnicas de refatoração segura e OBJETIVA

跳到安装

来源信息

仓库
criptogus/liquid-ai
最近来源活动
2026年1月25日 23:45
检测到的 SKILL.md 语言
葡萄牙语
星标
7
分支
2

安装方式

默认使用会先检查来源的 Prompt;你也可以切换为直接命令,或下载本地副本。

检查来源文件

决定是否安装前,请先阅读 SKILL.md,以及 SkillsMP 当前展示的配套文件。

正在显示 SKILL.md

SKILL.md
来源说明 · 只读预览
name
refactoring
description
Refactoring - Padrões e técnicas de refatoração segura e OBJETIVA
version
2.0.0
category
workflow
triggers
["refactoring","refatoração","refatorar","código legado","legacy code","code smell","clean code","technical debt","dívida técnica","melhorar código"]
tools
[]
author
liquid-ai
# Refactoring - Melhorando Código Existente Esta skill ajuda você a refatorar código de forma SEGURA e OBJETIVA. ## Regra Fundamental: OBJETIVIDADE ``` ┌─────────────────────────────────────────────────────────────┐ │ 🚨 REGRA MAIS IMPORTANTE: SEJA OBJETIVO E ÚTIL │ │ │ │ ❌ NUNCA RESPONDA ASSIM: │ │ "Existem várias formas de melhorar esse código..." │ │ "Depende do contexto..." │ │ "Você poderia considerar..." │ │ │ │ ✅ SEMPRE RESPONDA ASSIM: │ │ "Extraia esse bloco para função: extractPaymentLogic()" │ │ "Esse código tem 3 problemas: [lista específica]" │ │ "Refatore assim: [código exato]" │ │ │ │ DÊ O CÓDIGO REFATORADO, NÃO APENAS SUGESTÕES. │ └─────────────────────────────────────────────────────────────┘ ``` ## Princípio Fundamental ``` ┌─────────────────────────────────────────────────────────────┐ │ "Refactoring is the process of changing a software │ │ system in such a way that it does not alter the │ │ external behavior of the code yet improves its │ │ internal structure." - Martin Fowler │ │ │ │ COMPORTAMENTO IGUAL + ESTRUTURA MELHOR = REFACTORING │ │ │ │ Se muda comportamento → NÃO é refactoring │ │ Se não melhora estrutura → NÃO é refactoring │ └─────────────────────────────────────────────────────────────┘ ``` ## Quando Usar Esta Skill - Código difícil de entender ou modificar - Code smells identificados - Antes de adicionar nova feature - Depois de testes passando - Technical debt prioritizado ## O Ciclo de Refactoring ``` ┌─────────────────────────────────────────────────────────────┐ │ 1. GARANTA QUE TESTES EXISTEM E PASSAM │ │ → Se não tem testes, escreva primeiro │ │ → Testes são sua rede de segurança │ │ │ │ 2. FAÇA UMA PEQUENA MUDANÇA │ │ → Uma mudança por vez │ │ → Se algo quebrar, você sabe o quê │ │ │ │ 3. RODE OS TESTES │ │ → Todos devem passar │ │ → Se falhar: desfaça e tente de novo │ │ │ │ 4. REPITA │ │ → Pequenos passos seguros │ │ → Commit frequente │ │ │ │ "Make the change easy, then make the easy change." │ │ - Kent Beck │ └─────────────────────────────────────────────────────────────┘ ``` ## Code Smells e Soluções ### 1. Função Muito Longa ```typescript // ❌ ANTES: Função de 100+ linhas async function processOrder(order: Order) { // validação (20 linhas) if (!order.items) throw new Error('No items'); if (!order.customer) throw new Error('No customer'); // ... mais validações ... // cálculo de preço (30 linhas) let total = 0; for (const item of order.items) { total += item.price * item.quantity; // ... descontos, impostos ... } // processamento de pagamento (30 linhas) const payment = await chargeCard(order.customer.card, total); // ... tratamento de erros ... // envio de notificações (20 linhas) await sendEmail(order.customer.email, 'Order confirmed'); // ... mais notificações ... return { orderId: order.id, total, payment }; } // ✅ DEPOIS: Funções pequenas e focadas async function processOrder(order: Order) { validateOrder(order); const total = calculateTotal(order); const payment = await processPayment(order.customer, total); await sendNotifications(order, payment); return { orderId: order.id, total, payment }; } function validateOrder(order: Order): void { if (!order.items?.length) throw new Error('No items'); if (!order.customer) throw new Error('No customer'); } function calculateTotal(order: Order): number { return order.items.reduce((total, item) => total + item.price * item.quantity, 0); } async function processPayment(customer: Customer, total: number) { return await chargeCard(customer.card, total); } async function sendNotifications(order: Order, payment: Payment) { await sendEmail(order.customer.email, 'Order confirmed'); } ``` ### 2. Código Duplicado ```typescript // ❌ ANTES: Lógica duplicada function getUserDisplayName(user: User): string { if (user.firstName && user.lastName) { return `${user.firstName} ${user.lastName}`; } return user.email.split('@')[0]; } function getAdminDisplayName(admin: Admin): string { if (admin.firstName && admin.lastName) { return `${admin.firstName} ${admin.lastName}`; } return admin.email.split('@')[0]; } // ✅ DEPOIS: Extraia para função genérica interface HasName { firstName?: string; lastName?: string; email: string; } function getDisplayName(person: HasName): string { if (person.firstName && person.lastName) { return `${person.firstName} ${person.lastName}`; } return person.email.split('@')[0]; } // Uso getDisplayName(user); getDisplayName(admin); ``` ### 3. Muitos Parâmetros ```typescript // ❌ ANTES: 7 parâmetros function createUser( firstName: string, lastName: string, email: string, phone: string, address: string, city: string, country: string ) { // ... } // ✅ DEPOIS: Objeto de parâmetros interface CreateUserParams { firstName: string; lastName: string; email: string; phone?: string; address?: Address; } interface Address { street: string; city: string; country: string; } function createUser(params: CreateUserParams) { const { firstName, lastName, email, phone, address } = params; // ... } // Uso: mais legível, ordem não importa createUser({ firstName: 'João', lastName: 'Silva', email: 'joao@email.com', address: { street: 'Rua A', city: 'São Paulo', country: 'Brasil' } }); ``` ### 4. Condicionais Complexos ```typescript // ❌ ANTES: Nested ifs confusos function getDiscount(user: User, order: Order): number { if (user.isPremium) { if (order.total > 1000) { if (order.items.length > 5) { return 0.25; } else { return 0.20; } } else { return 0.15; } } else { if (order.total > 1000) { return 0.10; } else { return 0; } } } // ✅ DEPOIS: Early returns + funções descritivas function getDiscount(user: User, order: Order): number { if (!user.isPremium) { return order.total > 1000 ? 0.10 : 0; } if (order.total <= 1000) { return 0.15; } return order.items.length > 5 ? 0.25 : 0.20; } // OU: Ainda melhor com tabela de decisão const DISCOUNT_RULES = [ { premium: true, minTotal: 1000, minItems: 5, discount: 0.25 }, { premium: true, minTotal: 1000, minItems: 0, discount: 0.20 }, { premium: true, minTotal: 0, minItems: 0, discount: 0.15 }, { premium: false, minTotal: 1000, minItems: 0, discount: 0.10 }, { premium: false, minTotal: 0, minItems: 0, discount: 0.00 }, ]; function getDiscount(user: User, order: Order): number { const rule = DISCOUNT_RULES.find(r => r.premium === user.isPremium && order.total >= r.minTotal && order.items.length >= r.minItems ); return rule?.discount ?? 0; } ``` ### 5. Feature Envy ```typescript // ❌ ANTES: Classe acessa demais dados de outra class OrderService { calculateShipping(order: Order): number { // "Inveja" dos dados de Customer const address = order.customer.address; const city = address.city; const state = address.state; const isRemote = this.isRemoteArea(city, state); const weight = order.items.reduce((w, i) => w + i.weight, 0); if (isRemote) { return weight * 2.5; } return weight * 1.5; } } // ✅ DEPOIS: Mova lógica para onde estão os dados class Address { city: string; state: string; isRemoteArea(): boolean { // Lógica com os próprios dados return REMOTE_AREAS.includes(`${this.city}-${this.state}`); } } class Order { items: Item[]; customer: Customer; getTotalWeight(): number { return this.items.reduce((w, i) => w + i.weight, 0); } calculateShipping(): number { const baseRate = this.customer.address.isRemoteArea() ? 2.5 : 1.5; return this.getTotalWeight() * baseRate; } } ``` ## Refactorings Comuns ### Extract Function ``` QUANDO USAR: → Bloco de código faz uma coisa específica → Código se repete → Comentário explica o que o código faz COMO: 1. Crie função com nome descritivo 2. Copie o código 3. Identifique variáveis necessárias → parâmetros 4. Identifique variáveis modificadas → retorno 5. Substitua código original por chamada 6. Rode testes ``` ### Inline Function (oposto de Extract) ``` QUANDO USAR: → Função não adiciona clareza → Corpo é tão claro quanto o nome → Excesso de indireção EXEMPLO: // ❌ Indireção desnecessária function isAdult(age: number): boolean { return age >= 18; } function canVote(person: Person): boolean { return isAdult(person.age); } // ✅ Inline quando óbvio function canVote(person: Person): boolean { return person.age >= 18; } ``` ### Replace Temp with Query ```typescript // ❌ ANTES: Variável temporária function getPrice(order: Order): number { const basePrice = order.quantity * order.itemPrice; const discount = Math.max(0, order.quantity - 500) * order.itemPrice * 0.05; return basePrice - discount; } // ✅ DEPOIS: Métodos que expressam intenção function getPrice(order: Order): number { return getBasePrice(order) - getDiscount(order); } function getBasePrice(order: Order): number { return order.quantity * order.itemPrice; } function getDiscount(order: Order): number { return Math.max(0, order.quantity - 500) * order.itemPrice * 0.05; } ``` ### Replace Conditional with Polymorphism ```typescript // ❌ ANTES: Switch baseado em tipo function calculatePay(employee: Employee): number { switch (employee.type) { case 'hourly': return employee.hoursWorked * employee.hourlyRate; case 'salaried': return employee.monthlySalary; case 'commissioned': return employee.baseSalary + employee.sales * employee.commissionRate; } } // ✅ DEPOIS: Polimorfismo abstract class Employee { abstract calculatePay(): number; } class HourlyEmployee extends Employee { constructor(private hoursWorked: number, private hourlyRate: number) { super(); } calculatePay(): number { return this.hoursWorked * this.hourlyRate; } } class SalariedEmployee extends Employee { constructor(private monthlySalary: number) { super(); } calculatePay(): number { return this.monthlySalary; } } class CommissionedEmployee extends Employee { constructor( private baseSalary: number, private sales: number, private commissionRate: number ) { super(); } calculatePay(): number { return this.baseSalary + this.sales * this.commissionRate; } } ``` ## Checklist de Refactoring ``` ANTES DE REFATORAR: □ Testes existem e cobrem o código? □ Todos os testes passam? □ Você entende o que o código faz? □ O refactoring vai melhorar algo mensurável? DURANTE: □ Uma mudança pequena por vez? □ Rodando testes após cada mudança? □ Commits frequentes? □ Não mudando comportamento? DEPOIS: □ Todos os testes ainda passam? □ Código está mais legível? □ Menos duplicação? □ Nomes são claros? □ Funções são pequenas (<20 linhas)? ``` ## Exemplo de Resposta OBJETIVA **Usuário:** "Como refatoro este código?" ```javascript function calc(items, user) { let t = 0; for (let i = 0; i < items.length; i++) { t += items[i].p * items[i].q; if (items[i].p * items[i].q > 100) { t = t - (items[i].p * items[i].q * 0.1); } } if (user.premium) { t = t * 0.9; } return t; } ``` **Resposta:** ``` Este código tem 4 problemas: 1. Nomes ruins (t, p, q, calc) 2. Cálculo duplicado (items[i].p * items[i].q) 3. Lógica misturada (subtotal + desconto + premium) 4. Loop imperativo em vez de funcional CÓDIGO REFATORADO: interface CartItem { price: number; quantity: number; } interface User { isPremium: boolean; } function calculateCartTotal(items: CartItem[], user: User): number { const subtotal = calculateSubtotal(items); const itemDiscounts = calculateItemDiscounts(items); const premiumDiscount = calculatePremiumDiscount(subtotal, user); return subtotal - itemDiscounts - premiumDiscount; } function calculateSubtotal(items: CartItem[]): number { return items.reduce( (total, item) => total + getItemTotal(item), 0 ); } function getItemTotal(item: CartItem): number { return item.price * item.quantity; } function calculateItemDiscounts(items: CartItem[]): number { const BULK_DISCOUNT_THRESHOLD = 100; const BULK_DISCOUNT_RATE = 0.10; return items.reduce((discount, item) => { const itemTotal = getItemTotal(item); if (itemTotal > BULK_DISCOUNT_THRESHOLD) { return discount + itemTotal * BULK_DISCOUNT_RATE; } return discount; }, 0); } function calculatePremiumDiscount(subtotal: number, user: User): number { const PREMIUM_DISCOUNT_RATE = 0.10; return user.isPremium ? subtotal * PREMIUM_DISCOUNT_RATE : 0; } MELHORIAS: 1. Nomes descritivos (calculateCartTotal, price, quantity)
在 GitHub 查看
这个 SKILL.md 很大,SkillsMP 这里只预览前一段内容。 在 GitHub 查看