Home For SRP, How Do We Determine If a Class Has a "Single" Responsibility?
Post
Cancel

For SRP, How Do We Determine If a Class Has a "Single" Responsibility?

Many people think that SRP is the simplest principle in SOLID because they think that it is very easy to give modules a single responsibility. Actually, it’s not. In my opinion, SRP is the hardest principle in SOLID. If you have years of experience in software development, you know how difficult it is to maintain “single” responsibility for modules in real development. SRP, a cornerstone of the SOLID principles, is often misunderstood or oversimplified. In practical project development, very few developers are able to fully comply with this principle.

The Single Responsibility Principle is more than just a programming guideline; it’s a philosophy that promotes clarity, quality, and maintainability in software development. As we continue to evolve in the ever-changing landscape of technology, principles like SRP remain constant beacons, guiding us towards creating better, more sustainable software.

As OOP developers, our challenge is to continuously refine our understanding of what constitutes a single responsibility within the ever-evolving landscape of software development.


Contents


Introduction to SRP

What is the SRP?

The Single Responsibility Principle (SRP), famously defined by Robert C. Martin, asserts that a class should have only one reason to change. This means that each class should be responsible for a single aspect of the functionality provided by the software.

Why is SRP Important?

Simplifies Maintenance

  • Clear Focus: When a class is focused on a single task or responsibility, it’s easier to understand, update, and fix.
  • Fewer Side Effects: Changes in a single-responsibility class are less likely to impact other parts of the system.

Enhances Readability

  • Easier Understanding: New developers can more easily understand the structure and purpose of classes.
  • Better Organization: The codebase is more navigable with well-defined, single-purpose classes.

Facilitates Reusability

  • Modularity: SRP leads to modular code, where classes can be reused in different contexts.

Improves Testing

  • Simpler Tests: Classes with a single responsibility are easier to test due to fewer dependencies and scenarios to cover.

How Do We Determine If a Class Has a “Single” Responsibility?

Understanding the Essence of SRP

SRP is often misunderstood or oversimplified. It’s not just about having one function or method in a class; it’s about ensuring that a class has one reason to change.

A class can have multiple methods, but as long as these methods are aligned with a single responsibility or purpose, the class adheres to SRP. The “single responsibility” here depends on the specific project and even on the developer’s understanding of the module.

Some Techniques for Determining a Class’s Single Responsibility

Identify the Potential Axes of Change

  • Start by asking, “What are the different reasons that could lead this class to change?”
  • A class should have only one axis of change. For instance, a ReportGenerator class could change for formatting reasons but should not change for data retrieval logic.

Analyze the Cohesion of Methods

  • Assess if the methods within the class are closely related to each other.
  • Methods that operate on the same data or work together to achieve a common goal likely adhere to SRP.

Evaluate the Impact of Changes

  • Consider what happens if you change a particular method in the class.
  • If altering one method leads to modifications in others for different reasons, the class likely violates SRP.

Apply the Business Logic Separation Test

  • Can you describe the class’s responsibility without using the word “and” or “or”?
  • For instance, if a class is described as handling “user data storage and report generation”, it likely violates SRP.
  • Sometimes you may find it difficult to name a class appropriately, to summarise it in a business term. Or you can only use some general terms like Manager, Context and so on to name the class. This is a violation of the SRP

Consult with Stakeholders

  • Engage with those who understand the business domain.
  • Often, business stakeholders can provide insights on what constitutes a “single responsibility” in the context of the application’s purpose.

Practical Example of SRP

  • Consider a class named OrderProcessor. It might seem at first glance that it adheres to SRP. However, upon closer inspection, if it handles both order processing logic and database operations, it violates SRP.
    • These are two distinct axes of change:
      • one for business logic
      • the other for data persistence.
    • A change in the database schema should not force a change in the business logic and vice versa.

Actually, it is very difficult to come up with a suitable example of the SRP. To ensure that a module has a single responsibility, you must have a very clear understanding of both the SRP and related business logic of this module.

The class’s responsibility should not be as single as possible. If responsibilities are split too thinly, it reduces the cohesion of the code and also affects the maintainability of the code.

In real development, it is difficult to write SRP-compliant code at once. We can start by writing a rough-grained class that meets the business requirements. As the business grows, if the rough-grained class is getting bigger and bigger and the code is getting more and more numerous, at this time, we can take this rough-grained class and split it into several finer-grained classes. This is called continuous refactoring.

This post is licensed under CC BY 4.0 by the author.
ip