Keep Methods, Classes and Files Small
Shelfwise's checkout function is 80 lines long. A bug report says receipts sometimes show the wrong total, and fixing it means scrolling past stock checks and card-charging code to find the three lines that matter. Big units hide things. Small units put each thing where you would look for it.
The rule
One job per unit; if describing it needs "and", split it.
A unit is a function, a class or a file. Each should do one job that you can name in a few words.
def checkout(cart, customer):
ensure_in_stock(cart)
total = price_cart(cart, customer)
charge_card(customer, total)
send_receipt(customer, cart, total)This checkout is small because it only coordinates. The details live one level down, each in a function with a clear name. When the receipt total is wrong, you open price_cart and nothing else.
The same rule scales up. A class called OrderManager that prices, stores, emails and prints orders is four classes wearing one name. A 3,000-line file makes you search when you should be browsing. Group files by what they are about, such as orders/, payments/ and catalog/, so a newcomer can guess where a feature lives from the folder names alone.
Two companions keep units small over time:
- Keep it simple. Prefer the plainest code that passes the tests. Clever code is hard to split, and hard to read.
- Refactor often. Improve structure in small steps while you work in the code, with tests passing after each step. Leave each function a little tidier than you found it.
The shortcut
Describe the unit in one sentence. Every "and" is a seam where it can be cut.
Describe it
"It checks stock and prices the cart and charges the card and emails a receipt."
The trap is splitting by size instead of by job. Cutting a function at line 40 because it is long just gives you checkout_part_1 and checkout_part_2, two units with no clear job each.
Drills
Answer fast — trust the rule.
"place_order validates the cart and charges the card and emails a receipt." How many jobs does it have?
Which is the strongest sign a class is doing too much?
When is the best time to refactor?
Two versions of shipping_cost pass every test: a 6-line if and a 40-line plugin system nobody asked for. Which does "keep it simple" prefer?
A 90-line function is split at line 45 into process_a and process_b. What went wrong?
Remember
- One job per unit; every "and" in its description is a seam.
- Coordinators call small, well-named helpers; details live one level down.
- Trap: splitting by line count instead of by job.
