Single Responsibility Principle

Topics: SOLID Principles

The SRP is the first of the SOLID Principles. See also Separation of Concerns.

“A class should have one, and only one, reason to change.”
– Robert C. Martin
A module/class/function should only have a single responsibility, that is, only changes to one part of the software’s specification should be able to affect the specification of the module/class/function.

A module/class/function should

  • be responsible only and fully for a single part of the functionality, and
  • have all its services narrowly aligned with that responsibility.

Advantages

  • Code becomes more reusable
  • Separate responsibilities are only loosely coupled and can be replaced easily
  • Single responsibilities can be tested in isolation

Example

class TwitchStats
  def initialize(daily_viewers:)
    @stats = daily_viewers
  end

  def report
    sum = 0
    stats.each_pair { |day, viewers| sum = sum + viewers }
    puts "Total viewers: #{sum}"
    avg = sum / stats.length
    puts "Average viewers per day: #{avg}"
  end
  
  private
    attr_reader :stats
end

In this class, the report method does more than just calculate the results, it also formats them into strings which it then outputs to the screen.

  • This makes it less reusable because neither can we get the raw results alone nor can we influence the output formatting.
  • We can’t build tests for the method because it doesn’t return any useable data.

Antipatterns

Kitchen sink class

Boolean method arguments

A method that takes a Boolean argument by definition has two responsibilities; one for a value of true, another for false.