The Quest Begins (The “Why”)
I still remember the first time I opened a pull request that looked like a novel written by someone who’d never heard of paragraphs. The file was a single 300‑line function called processUserRequest. It validated input, talked to three different services, built a response, logged everything, and even tried to make coffee (okay, not really, but it felt that way). As I scrolled, my eyes glazed over, and I kept thinking, “Where does this thing even start?”
After spending two hours just trying to understand what the author intended to do, I missed a subtle bug: a stray null check that let a malformed ID slip through to the payment gateway. The incident cost us a few angry customers and a late‑night pager alert. That moment hit me like a plot twist in a bad sitcom—I was the one who let the villain slip through the cracks because the code was impossible to review.
I realized that if I wanted my teammates (and future me) to actually see what I was doing, I had to change how I wrote code, not just how I reviewed it. The quest was on: find a simple habit that makes every diff a joy to read instead of a chore to survive.
The Revelation (The Insight)
The treasure I uncovered wasn’t a fancy tool or a new framework—it was a mindset shift: write small, focused functions that each do ONE thing.
When a function has a single, clear responsibility, the reviewer can glance at its name, read its signature, and instantly know what it’s trying to accomplish. There’s no mental juggling act, no hidden side‑effects lurking in a 50‑line block. It’s like handing someone a well‑labeled toolbox instead of a tangled mess of cables.
This practice does more than make reviews faster; it reshapes the way you think while you’re coding. You start asking, “What is the smallest piece of work I can extract here?” Before you know it, you’re writing code that’s easier to test, easier to reuse, and far less likely to hide bugs in plain sight.
Wielding the Power (Code & Examples)
Let’s look at a realistic scenario: processing an online order. Below is the kind of monster I used to write (and dread reviewing).
// BEFORE – the “all‑in‑one” beast
function processOrder(order) {
// 1️⃣ Validate
if (!order.id || !order.items.length) {
throw new Error('Invalid order');
}
for (const item of order.items) {
if (item.quantity <= 0) throw new Error('Quantity must be > 0');
}
// 2️⃣ Calculate tax (simplified)
let tax = 0;
for (const item of order.items) {
tax += item.price * item.quantity * 0.08; // 8% tax
}
// 3️⃣ Apply discount
let discount = 0;
if (order.total > 100) {
discount = order.total * 0.1; // 10% off big orders
}
// 4️⃣ Update inventory (pretend DB call)
for (const item of order.items) {
inventoryDb.decrement(item.sku, item.quantity);
}
// 5️⃣ Persist order
const saved = orderDb.save({
...order,
tax,
discount,
finalTotal: order.total + tax - discount,
status: 'processed',
});
// 6️⃣ Send confirmation email (another external call)
emailService.send(order.customer.email, 'Your order is confirmed!', `Thanks!`);
return saved;
}
What’s wrong here?
- A reviewer must keep track of validation, tax, discount, inventory, persistence, and notification—all in one mental stack.
- If the tax calculation changes, you have to hunt through the whole function, risking unintended side‑effects.
- Unit testing means mocking everything just to test a tiny piece of logic.
Now, watch the same logic after applying the “single responsibility” spell:
// AFTER – tiny, intent‑revealing helpers
function validateOrder(order) {
if (!order.id || !order.items.length) {
throw new Error('Invalid order');
}
for (const item of order.items) {
if (item.quantity <= 0) throw new Error('Quantity must be > 0');
}
}
function calculateTax(items) {
return items.reduce((sum, item) => sum + item.price * item.quantity * 0.08, 0);
}
function applyDiscount(subtotal) {
return subtotal > 100 ? subtotal * 0.1 : 0;
}
function reserveInventory(items) {
for (const item of items) {
inventoryDb.decrement(item.sku, item.quantity);
}
}
function persistOrder(order, tax, discount) {
return orderDb.save({
...order,
tax,
discount,
finalTotal: order.total + tax - discount,
status: 'processed',
});
}
function sendConfirmation(customerEmail) {
emailService.send(customerEmail, 'Your order is confirmed!', 'Thanks!');
}
// Orchestrator – still short, but each line is a clear step
function processOrder(order) {
validateOrder(order);
const tax = calculateTax(order.items);
const discount = applyDiscount(order.total);
reserveInventory(order.items);
const saved = persistOrder(order, tax, discount);
sendConfirmation(order.customer.email);
return saved;
}
Why this feels like a victory:
- Each helper does one thing and is instantly understandable from its name.
- The orchestrator (
processOrder) now reads like a high‑level recipe: validate → tax → discount → inventory → save → notify. - If the tax rule changes, I only touch
calculateTax. No risk of accidentally altering inventory logic. - Writing unit tests is a breeze: I can test
calculateTaxwith a simple array of items, mock-free. - During review, my teammates can skim the PR, see that each function is tiny and focused, and spend their time on the real design decisions instead of deciphering spaghetti.
Why This New Power Matters
Adopting this habit turned my code reviews from dreaded inspections into quick, confident walkthroughs. I’ve caught fewer bugs in production because each piece is isolated and testable. My teammates actually enjoy looking at my PRs—they say it’s like reading a well‑structured story instead of deciphering cryptic runes.
And the best part? The practice is contagious. When others see how clean and approachable the diffs become, they start extracting their own helpers, and the whole codebase begins to feel more maintainable. It’s a small shift that yields outsized returns—kind of like discovering a hidden shortcut in a game that lets you skip the grind and head straight for the boss fight.
Your Turn, Adventurer
Grab a function you’ve written recently that feels a little too long. Ask yourself: “What is the smallest piece of work I can pull out of this?” Extract it, give it a clear name, and watch the rest of the function shrink.
Challenge: Pick one function from your current branch, split it into at least two smaller, single‑responsibility functions, and open a PR just for that refactor. Comment on how the review felt—did it feel smoother? Did you spot anything you missed before?
May your code be as clear as a Jedi’s intent, and may your reviews be swift and victorious. Happy hacking! 🚀
Top comments (0)