5 Code Refactoring Techniques Every Developer Should Know
2026-06-18
Why Refactoring Matters
Refactoring is the art of improving code without changing its behavior. It keeps your codebase healthy, reduces bugs, and makes future changes faster.
1. Extract Method
When a function does too many things, extract parts of it into named methods:
// Before: one function does everything
function processOrder(order) {
// Validate
if (!order.items || order.items.length === 0) throw new Error("Empty order");
if (!order.customer.email) throw new Error("Missing customer email");
// Calculate
let total = 0;
for (const item of order.items) {
total += item.price * item.quantity;
}
const tax = total * 0.08;
const finalTotal = total + tax;
// Send
sendEmail(order.customer.email, "Order Confirmed", `Total: $${finalTotal}`);
return finalTotal;
}
// After: extracted into focused methods
function processOrder(order) {
validateOrder(order);
const total = calculateTotal(order);
sendConfirmation(order.customer.email, total);
return total;
}
function validateOrder(order) {
if (!order.items?.length) throw new Error("Empty order");
if (!order.customer?.email) throw new Error("Missing email");
}
function calculateTotal(order) {
const subtotal = order.items.reduce((sum, item) => sum + item.price * item.quantity, 0);
return subtotal * 1.08; // 8% tax
}
2. Replace Nested Conditional with Guard Clauses
Deep nesting obscures logic. Return early:
// Before
function processPayment(payment) {
if (payment) {
if (payment.amount > 0) {
if (payment.method === "credit_card") {
return chargeCard(payment);
} else {
return "Unsupported method";
}
} else {
return "Invalid amount";
}
} else {
return "No payment provided";
}
}
// After
function processPayment(payment) {
if (!payment) return "No payment provided";
if (payment.amount <= 0) return "Invalid amount";
if (payment.method === "credit_card") return chargeCard(payment);
return "Unsupported method";
}
3. Replace Conditional with Polymorphism
Instead of switch-on-type, use object lookup:
// Before
function calculateShipping(method, weight) {
if (method === "standard") return weight * 0.5;
if (method === "express") return weight * 1.5 + 5;
if (method === "overnight") return weight * 3 + 10;
return weight * 0.5;
}
// After
const shippingRates = {
standard: (w) => w * 0.5,
express: (w) => w * 1.5 + 5,
overnight: (w) => w * 3 + 10,
};
function calculateShipping(method, weight) {
return (shippingRates[method] || shippingRates.standard)(weight);
}
4. Decompose Complex Conditions
Break complex if-statements into named variables:
// Before
if (user.age >= 18 && user.country === "US" && !user.isBanned && user.verifiedEmail) {
grantAccess(user);
}
// After
const isAdult = user.age >= 18;
const isUSResident = user.country === "US";
const isGoodStanding = !user.isBanned && user.verifiedEmail;
if (isAdult && isUSResident && isGoodStanding) {
grantAccess(user);
}
5. Consolidate Duplicate Conditionals
// Before
if (isSpecialDay) {
price = basePrice * 0.9;
notification = "Special discount applied!";
}
if (isSpecialDay) {
logEvent("special_discount");
}
// After
if (isSpecialDay) {
price = basePrice * 0.9;
notification = "Special discount applied!";
logEvent("special_discount");
}
Try the If-Else Refactor Tool
Use the If-Else Refactor Tool on YZIF to automatically transform nested conditionals into clean guard clauses, switch statements, or strategy patterns.