Understanding the Single Responsibility Principle (SRP) for Beginners

Noyon RahmanNoyon Rahman
4 min read

One of the simplest ways to make your code easier to read, test, and maintain is by following the Single Responsibility Principle (SRP). SRP is a core part of the SOLID principles in software design and is all about giving each function, method, or class one specific job.

Think of SRP as organizing tools in a toolbox: each tool has its purpose—a hammer for nails, a screwdriver for screws. If you have one tool that tries to do everything, it’ll make a mess. In the same way, each function or method in your code should do just one thing. Code is cleaner and much easier to work with when everything has its place.


What is the Single Responsibility Principle?

The Single Responsibility Principle says that each piece of code should have one reason to change—in other words, a single job to focus on. By following SRP, you keep your code neat and prevent it from becoming overly complicated.

Why SRP Matters

Following SRP has some solid benefits:

  • Easier to Read: Focused functions are easier to understand at a glance.

  • More Maintainable: When code has one clear job, changes don’t break multiple things.

  • More Reusable: A function that does one thing can be reused in different parts of your application without side effects.


SRP in Action

Imagine you need to create a function to calculate a total and add some extra information, like the user who calculated it and the timestamp. Writing one big function for this is tempting, but that often leads to problems.

Let’s walk through a good and bad example to see how following SRP makes the code easier to work with.

Bad Example: Doing Too Much in One Function

Here’s a function that tries to calculate the total and build an object with extra details.

// This function calculates the total and creates an object in one step
function calculateTotalAndReturnRecord(a, b, user) {
    let sum = a + b;
    return {
        user: user,
        total: sum,
        timestamp: new Date()
    };
}

let record = calculateTotalAndReturnRecord(5, 10, "Shahan");
console.log(record);

👎 Why This is Bad

This function does two things: it calculates the total and creates an object with extra information. This approach can cause a few issues:

  • Harder to Maintain: If you only want to change how the total is calculated, you’ll still have to dig into this function and mess with the object creation part too.

  • Testing is Tougher: Testing each part independently becomes difficult because you can’t easily separate the calculation from the object structure.

  • Reuse Issues: If you want to reuse the calculation part, you can’t do that without the record-building logic tagging along.


Good Example: Separate Tasks into Focused Functions

Let’s refactor the code by splitting it into two separate functions: one that only calculates the total and another that builds the record object.

// This function only calculates the total
function calculateTotal(a, b) {
    return a + b;
}

// This function creates an object with extra details
function createCalculationRecord(a, b, user) {
    let sum = calculateTotal(a, b); // Calls the calculate function
    return {
        user: user,
        total: sum,
        timestamp: new Date()
    };
}

let record = createCalculationRecord(5, 10, "Shahan");
console.log(record);

👍 Why This is Good

Here’s why breaking things up like this is better:

  • Clear Responsibilities: calculateTotal is only responsible for doing the math. createCalculationRecord handles building the record.

  • Easier to Maintain: If you want to change how the total is calculated, you only need to update calculateTotal. If the record format changes, you update createCalculationRecord.

  • Easier Testing and Reuse: Now, you can test each function independently and reuse calculateTotal without worrying about any other tasks.


Key Takeaways

The Single Responsibility Principle is about keeping your code organized and manageable:

  • Each function or class should have one job.

  • Avoid making functions do too many unrelated things.

  • Following SRP makes code easier to read, update, and reuse.

Taking a few extra minutes to break things up pays off later, making your code simpler to work with in the long run. When each part of your code has a specific job, you spend less time untangling it and more time building something cool.


Final Thoughts

SRP is a small change that can make a big difference in your code quality. When you give each function or method just one responsibility, your code becomes more flexible, easier to understand, and much less frustrating to maintain. So, as you write or refactor your code, ask yourself: Does this function have only one job? If not, it might be time to split it up.

Happy coding! 🙂

1
Subscribe to my newsletter

Read articles from Noyon Rahman directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Noyon Rahman
Noyon Rahman

I build things for the web!