Any fool can write code that a computer can understand. Good programmers write code that humans can understand. — Martin Fowler
Functions and methods are the fundamental building blocks of any codebase. Every line of code we write lives within a function. Writing clean, well-designed functions is essential for creating maintainable, readable, and scalable software.
⚙️ Anatomy of a Function
Every function consists of three essential components:
Component
Description
Coverage
Name
How the function is identified
See Naming section
Parameters
The data inputs it accepts
Covered here
Body
The implementation logic
Covered here
This guide focuses on crafting clean parameters and function bodies.
🧩 Minimize the Number of Parameters
Core Principle: The fewer parameters a function has, the easier it is to read, call, and understand.
❌ What Not to Do
Problems:
⚠️ Must memorize parameter order
⚠️ Unclear why values are duplicated ('Max' appears twice)
⚠️ Hard to parse at a glance
⚠️ Prone to errors when calling
📊 Parameter Guidelines
Count
Rating
Description
Example
0
⭐⭐⭐⭐⭐
Ideal clarity
createSession()
1
⭐⭐⭐⭐
Straightforward
isValid(email)
2
⭐⭐⭐
Acceptable if intuitive
login(email, password)
3+
⚠️
Avoid when possible
createRect(10, 9, 30, 12)
Examples by Parameter Count
Zero Parameters — Perfect Clarity
One Parameter — Simple & Flexible
Two Parameters — Context Matters
✅ Clear and intuitive:
⚠️ Ambiguous ordering:
❌ Hard to use:
✅ Solution: Use Structured Objects
Transform multiple parameters into self-documenting objects:
Before:
After:
Benefits:
✅ Self-documenting code
✅ No ordering dependencies
✅ Easy to add optional parameters
✅ Better IDE autocomplete support
🪶 Keep Functions Small
Core Principle: Smaller functions are easier to read, test, maintain, and reuse.
Why Small Functions Matter
📖 Less cognitive load — Easier to understand at a glance
🧪 Better testability — Simpler to write unit tests
♻️ Higher reusability — More focused, single-purpose functions
🐛 Easier debugging — Smaller surface area for bugs
📝 Self-documentation — Good names describe what the function does
Real-World Example
❌ Before: Long & Complex
Problems:
Too many responsibilities mixed
Hard to test individual steps
Difficult to maintain or modify
Not reusable
✅ After: Small & Focused
Benefits:
✨ Clear, scannable logic
✨ Each step can be tested independently
✨ Easy to modify validation or session logic
✨ Functions can be reused elsewhere
🎯 Do One Thing
Core Principle: Each function should do one thing, do it well, and do it only.
Understanding "One Thing"
Consider this function:
Question: Is this doing "one thing"?
You might argue it does three things:
Validate user input
Verify credentials
Create a session
Answer: This function IS doing one thing — logging in a user. All three operations are steps required to accomplish that single goal.
🔑 The Key Principle
A function does "one thing" if all operations in the function body are:
On the same level of abstraction
One level below the function name
Good Example
All operations are:
✅ At the same abstraction level (high-level orchestration)
✅ One level below "process order"
✅ Necessary steps for the single goal
Bad Example
Problems:
❌ Mixing abstraction levels (high-level charging with low-level loops)
❌ Implementation details exposed
❌ Hard to test individual pieces
🧱 Levels of Abstraction
Core Principle: Maintain consistent abstraction levels within functions.
Understanding abstraction is crucial for writing clean, maintainable code.