What does single responsibility mean for a function
single responsibility principle, function cohesion, reasons to change, side effects, functional purity basics
Single Responsibility: One Function, One Job
A function should do one thing. That sounds obvious — but most functions you'll encounter in real codebases do three or four things at once. The rule is simple to state and hard to follow without practice.
Here's what "one thing" actually means: if you can describe what a function does using "and," it does too much.
// Does too much — validate AND save AND notify
function submitUserRegistration(user) {
if (!user.email.includes('@')) throw new Error('Invalid email');
db.users.insert(user);
emailService.sendWelcome(user.email);
}Split it into three functions, each with one job:
function validateUserEmail(email) {
if (!email.includes('@')) throw new Error('Invalid email');
}
function saveUser(user) {
return db.users.insert(user);
}
function sendWelcomeEmail(email) {
return emailService.sendWelcome(email);
}
// Orchestrator — reads like a sentence
function registerUser(user) {
validateUserEmail(user.email);
saveUser(user);
sendWelcomeEmail(user.email);
}The orchestrator registerUser is fine — it coordinates multiple steps, but each step it calls is a single-purpose function. This pattern separates concerns without sacrificing readability.
Why does this matter? When email sending breaks, you open sendWelcomeEmail. You don't search through a 50-line function that mixes validation, database calls, and email logic. Each function has exactly one reason to change — and that makes debugging and testing dramatically faster.
