Buy Me A Coffee
Site Logo
Site Title Banner
Software Engineering

Writing Clean Functions: The Single Responsibility Principle in Practice

How to write functions that do one thing well — and why it makes your codebase dramatically easier to maintain.

Jeff
Reading time: 1 min
intermediate
clean code single responsibility principle functions refactoring software engineering #clean-code #software-engineering #best-practices #refactoring

Good functions are the building blocks of good software. Yet it is surprisingly easy to write functions that do too much, know too much, or mean too little.

The Single Responsibility Principle

The Single Responsibility Principle (SRP) states that a function should do one thing, do it well, and do it only. When a function has a single, clear purpose, it becomes:

  • Easier to name
  • Easier to test
  • Easier to reuse
  • Easier to change without fear

If you find yourself reaching for the word “and” when describing what a function does, it is doing too much.

A Practical Example

Consider this function:

def process_user(user_data):
    # Validate
    if not user_data.get("email"):
        raise ValueError("Email required")
    # Save to DB
    db.save(user_data)
    # Send welcome email
    send_email(user_data["email"], "Welcome!")

This function validates, persists, and sends an email. It has three reasons to change. Split it:

def validate_user(user_data):
    if not user_data.get("email"):
        raise ValueError("Email required")

def save_user(user_data):
    db.save(user_data)

def send_welcome_email(email):
    send_email(email, "Welcome!")

Now each function is independently testable and replaceable.

Naming Is a Signal

If you struggle to name a function without using vague words like handle, process, or manage, that is a signal the function is doing too much. A well-scoped function almost names itself.

Keep Functions Short

Short functions are not a goal in themselves, but they are a natural outcome of good design. A function that fits on one screen is one you can reason about without scrolling.

Aim for functions where the abstraction level is consistent throughout — don’t mix high-level orchestration with low-level implementation details in the same function.

Conclusion

Clean functions are a discipline, not a talent. The habit of asking “does this function do exactly one thing?” pays compounding dividends as a codebase grows.

Share this article

Published on 1 October 2024

Last updated: 1 October 2024