The Single Responsibility Principle

Learn about the single responsibility principle (SRP) in software design.

The single responsibility principle (SRP) states that a software component (in general, a class) must have only one responsibility. This means that it is in charge of doing just one concrete thing, and as a consequence of that, we can conclude that it must only have one reason to change.

We should only have to update the class if one specific thing in the domain problem changes. If we have to make modifications to a class for different reasons, it means the abstraction is incorrect and that the class has too many responsibilities. This might be an indication that there is at least one abstraction missing: more objects need to be created to address the extra responsibility that's overloading the class in question.

This design principle helps us build more cohesive abstractions—objects that do one thing, and just one thing, well, which follows the Unix philosophy. What we want to avoid in all cases is having objects with multiple responsibilities (often called God objects, because they know too much, or more than they should). These objects group different (mostly unrelated) behaviors, thus making them harder to maintain.

Again, the smaller the class, the better.

The SRP is closely related to the idea of cohesion in software design, which we already explored when we discussed the separation of concerns in software. What we strive to achieve here is that classes are designed in such a way that most of their properties and their attributes are used by their methods, most of the time. When this happens, we know they are related concepts, and therefore it makes sense to group them under the same abstraction.

In a way, this idea is somewhat analogous to the concept of normalization in relational database design. When we detect that there are partitions on the attributes or methods of the interface of an object, they might as well be moved somewhere else—it is a sign that they are two or more different abstractions mixed into one.

There is another way of looking at this principle. If, when looking at a class, we find methods that are mutually exclusive and do not relate to each other, they are the different responsibilities that have to be broken down into smaller classes.

A class with too many responsibilities

In this example, we are going to create a case for an application that is in charge of reading information about events from a source (this could be log files, a database, or many more sources), and identify the actions corresponding to each particular log.

A design that fails to conform to the SRP would look like this.

Get hands-on with 1200+ tech skills courses.