Single Responsibility Principle

One Class — One Reason to Change

The Single Responsibility Principle (SRP) states that a class should have only one reason to change.

“A class should have only one reason to change.” — Robert C. Martin

Simply put:

One class = one responsibility.

This means that a class may perform multiple operations, but they should all belong to a single, clearly defined area of responsibility.

Real-Life Example: How to Understand It?

Imagine an employee in a company who is responsible for:

  • answering phone calls,
  • handling accounting,
  • repairing computers,
  • recruiting new employees.

At first glance, this may seem efficient — one person handles everything. However, problems arise whenever changes occur in any of these areas.

Change in Accounting

The company introduces new tax regulations or changes the invoicing process. The employee must learn new procedures and adapt the way they perform accounting tasks.

Change in Recruitment

The HR department decides to add a new stage to the interview process or modify candidate application forms. Once again, the same employee must adjust their work, even though this change has nothing to do with accounting.

As a result, a single person becomes dependent on changes occurring in many completely different areas of the business. Every new procedure, regulation, or requirement forces them to modify the way they work.

The exact same problem occurs in software development.

If a single class:

  • saves data to a database,
  • sends emails,
  • generates reports,
  • prints documents,

then every change in any of these areas requires modifications to the same class.

As a consequence:

  • the code becomes larger and more complex,
  • the risk of introducing bugs increases,
  • testing becomes more difficult,
  • understanding the class’s responsibility becomes harder.

According to SRP, it would be better to hire four specialists:

  • an accountant,
  • a recruiter,
  • an IT specialist,
  • a customer service representative.

In software development, the equivalent of these specialists is a set of separate classes, each responsible for a specific area. This way, a change in accounting does not affect the IT specialist’s work, and changes in recruitment do not require modifications to customer service processes.

This is exactly what “one reason to change” means.

Example — SRP Violation

Suppose we are building an e-commerce system.

The OrderService class below violates SRP because it has three reasons to change:

  • saving orders,
  • sending emails,
  • printing invoices.
class OrderService {
 
    public void saveOrder(Order order) {
        // save to database
    }
 
    public void sendConfirmationEmail(Order order) {
        // send email to customer
    }
 
    public void printInvoice(Order order) {
        // print invoice
    }
}

The class has three different reasons to change:

If the data storage mechanism changes (for example, migrating from MySQL to PostgreSQL):

public void saveOrder(Order order) {
    // save to database
}

If the email delivery method changes:

public void sendConfirmationEmail(Order order) {
    // send email to customer
}

If the invoice format changes (for example, a new field must be added):

public void printInvoice(Order order) {
    // print invoice
}

Where Does the Change Come From? The Actor Concept

It is worth asking: who causes changes to each method in the OrderService class?

  • Changes in saveOrder() may be required by the infrastructure team, for example, due to a database migration from MySQL to PostgreSQL.
  • Changes in sendConfirmationEmail() may be required by the marketing department, for example, due to a new email template.
  • Changes in printInvoice() may be required by the accounting department, for example, because a new field must appear on invoices.

In Robert C. Martin’s terminology, each of these entities is an actor — a specific person or team responsible for a business area and the only one who should have a reason to request changes in a class.

“A module should be responsible to one, and only one, actor.” — Robert C. Martin, Clean Architecture

If three different people from three different departments can independently request modifications to the same class, that is a strong indication that the class violates SRP.

This is why the definition talks about a reason to change, not the number of methods.

A class may contain many methods and still comply with SRP,

provided that all changes are driven by decisions from the same actor.

Example — SRP Compliant Design

We separate responsibilities into dedicated classes:

class OrderRepository {
 
    public void save(Order order) {
        // save to database
    }
}
 
class EmailService {
 
    public void sendConfirmation(Order order) {
        // send email to customer
    }
}
 
class InvoicePrinter {
 
    public void print(Order order) {
        // print invoice
    }
}

What Do We Gain?

Each class is responsible for a single area:

  • OrderRepository is responsible for data persistence.
  • EmailService is responsible for sending emails.
  • InvoicePrinter is responsible for generating and printing invoices.

If the email delivery mechanism changes, we modify only the EmailService class.

If the invoice format changes, we modify only the InvoicePrinter class.

Why Is SRP Important?

Easier to Understand

Instead of one class containing 1,000 lines of code and performing 20 different tasks, we create classes whose names clearly indicate their responsibilities.

Easier Maintenance

Changes made in one area do not trigger a chain reaction of modifications throughout the system.

Easier Testing

Testing a class with a single responsibility is much easier than testing a class that performs many unrelated functions.

Lower Risk of Bugs

When modifying code responsible for sending emails, we do not risk accidentally breaking invoice-related functionality.

When Should You Apply SRP?

Apply SRP when:

  • a class has more than one reason to change,
  • modifying one feature requires changes in unrelated parts of the class,
  • testing a class is difficult because it does too much,
  • a class contains many unrelated methods,
  • it is difficult to describe the class’s responsibility in a single sentence.

A good class does one thing well.

As a result, the code becomes simpler, more readable, easier to test, and easier to maintain and extend.

CATEGORIES:

SOLID Principles

No responses yet

Leave a Reply

Your email address will not be published. Required fields are marked *

Latest Comments

No comments to show.