Image for post
Image for post
Photo by Roman Kraft on Unsplash

SOLID — The Dependency Inversion Principle

🎉 You can find new and updated posts at ellehallal.dev

This is a quick blog on my understanding of dependency inversion. There are still elements I am unsure about, so please feel free to leave feedback.

High-level modules should not depend on low-level modules. Both should depend on abstractions.

Abstractions should not depend on details. Details should depend on abstractions.

— Robert C. Martin

That’s great, but what does it mean? 🤷🏽‍♀️ I’ll demonstrate my understanding by using a class in my Tic Tac Toe application as an example.

In the application, there’s a class called GameFactory. The purpose of GameFactory is to create an instance of the Game class with the specified players and a board.

Here’s a condensed version of the class:

class GameFactory
def initialize(player_factory)
@player_factory = player_factory
end
def new_game(squares)
board = Board.new(squares)
player1 = @player_factory.create_player('x', 1)
player2 = @player_factory.create_player('o', 2)
Game.new(board, player1, player2)
end
end

In the new_game method, new instances of the Board and Game classes are created within it. However, this violates the Dependency Inversion Principle.

What’s wrong with it?

The high-level class GameFactory is dependent on the low level classesBoard and Game As a result, they are tightly coupled. A change in a low-level class will affect the high-level class.

If the name of the Board or Game class was changed, the new_game method within GameFactory wouldn’t work. As a result, it would need to be amended to accommodate the renamed classes.

If sub classes of Board and Game were to be used to create a new game, (for example, BestBoard and FunGame) the new_game method would need to be changed again to accommodate this.

A method to resolve the above issues is to pass the classes into GameFactory's constructor:

class GameFactory
def initialize(player_factory, board, game)
@player_factory = player_factory
@board = board
@game = game
end
def new_game(squares)
board = @board.new(squares)
player1 = @player_factory.create_player('x', 1)
player2 = @player_factory.create_player('o', 2)
@game.new(board, player1, player2)
end
end

Whatever is passed in as board and game during initialisation, becomes @board and @game within GameFactory.

If the names of the Board and Game classes were to change, initialising GameFactory with the renamed classes would not affect GameFactory.

If subclasses of Board and Game (
for example, BestBoard and FunGame) were used to initialise an instance of GameFactory, this would not affect how new_game functions.

Written by

This blog is no longer updated. Please visit → https://ellehallal.dev Software Crafter at 8th Light. Leadership Team Member & Mentor at Coding Black Females

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store