Dependency Inversion Principle in Ruby

Dependency Inversion Principle in Ruby

Simply Dependency Inversion Principle states that: Abstractions should not depend upon details. Details should depend upon abstractions.

Let’s go back to the first example on the Open/Closed Principle and change it a bit:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Report
  def body
    generate_reporty_stuff
  end

  def print
    JSONFormatter.new.format(body)
  end
end

class JSONFormatter
  def format(body)
    ...
  end
end

Now there is a formatter class, but I’ve hardcoded it on the Report class, thus creating a dependency from the Report to the JSONFormatter. Since the Report is a more abstract (high-level) concept than the JSONFormatter, we’re effectively breaking the DIP.

We can solve it the exact same way with solved it on the Open/Closed Principle problem, with dependency injection:

1
2
3
4
5
6
7
8
9
class Report
  def body
    generate_reporty_stuff
  end

  def print(formatter: JSONFormatter.new)
    formatter.format body
  end
end

So far so good, this way the Report does not depend on the JSONFormatter and can use any type of formatter that has a method called format (this is known as duck typing). That’s it!!! See ya!!! :)