One Order Function That Reveals All Six Principles
Take a small online store. The first version can compute an order total, apply a discount, and add a delivery cost. The requirement looks simple, so the developer writes it all in one function.
function calculateOrder(order) {
let subtotal = 0;
for (const item of order.items) {
subtotal += item.price * item.quantity;
}
let discount = subtotal > 10000 ? subtotal * 0.1 : 0;
let delivery = subtotal > 5000 ? 0 : 500;
return subtotal - discount + delivery;
}The code works: a test order returns the right total. This is exactly the moment when it's easiest to start "improving the architecture" just because we know pretty words. But first it's worth seeing the solution's real properties. What's already fine here: the formula reads top to bottom, with no factories, containers, or abstract providers - for a first version that's a virtue, not a flaw. What's concerning: the function knows the discount rules, the delivery rules, and the order structure all at once. If those parts start changing independently, one function becomes a point of constant conflicts.
The problem isn't in today's code but in its trajectory.
- Today: one discount rule, one delivery option
- In a month: promo codes, customer tiers, two carriers
- In half a year: marketing and logistics change rules independently
The first skill isn't about patterns. Don't ask which pattern to insert here. Ask which part of the code already creates a measurable problem. While there's no problem, there's nothing to "solve" in advance.
We'll return to this function in every practice and watch which principle answers the next real change. Let's start with the earliest question: is the solution simple enough.