Tic Tac Toe and The Single Responsibility Principle

Share on facebook
Share on google
Share on twitter
Share on linkedin
Photo by Kelly Sikkema on Unsplash

This is a quick blog on my understanding of the Single Responsibility principle, and implementing it in a Tic Tac Toe game.

What is the Single Responsibility Principle (SRP)?

SRP is one of the five SOLID principles of object-oriented programming. The intention is to “make software designs more understandable, flexible and maintainable”.

SRP is the concept that a class should have one responsibility, and therefore only one reason to change.

Implementing SRP in Tic Tac Toe

I’m currently working on a Tic Tac Toe game in Ruby, where I have been provided with a number of user stories. The first user story is: as a user, I can see the initial board.

Breaking this down, my understanding is there needs to be a Tic Tac Toe board, and the user needs to be able to see it.

Creating The Board

class Board  
  attr_reader :board

  def initialize(board)
    @board = board
  end
end

Above, the Board class takes a board as an argument when initialised. For a Tic Tac Toe game, an array containing numbers 1–9 will be passed when an instance of Board is initialised.

board = Board.new([1, 2, 3, 4, 5, 6, 7, 8, 9])

Displaying The Board

To show the Tic Tac Toe board, a method is needed to show the output to the user. For example:

def display_board(board)
  print """
   #{board[0]} | #{board[1]} | #{board[2]}
  -----------
   #{board[3]} | #{board[4]} | #{board[5]}
  -----------
   #{board[6]} | #{board[7]} | #{board[8]}n"""
end

It would be natural to assume this method should be within the Board class, simply because that is where the Tic Tac Toe board lives.

However, what if changes were to occur in the future? For example, if the application was to become web-based, rather than command line based, display_board would be a redundant method. As a result, it is likely that any methods within Board containing output would need to be changed.

What would happen if all output was contained within a separate class? In the case above, the Board class wouldn’t need to be amended because it doesn’t contain methods that are printing to the command line.

With this in mind, a new class called Display, was created with the display_board method added:

class Display
  def display_board(board)
    ...
  end
end

For other user stories, where printing a message to the command line is needed, such as prompting the user for a move and displaying the current player, it will be contained within this class.

In conclusion

By implementing the Single Responsibility principle, the Board and Display classes have one responsibility each and only one reason to change.

The Board class manages the state of the Tic Tac Toe board. In relation to the user story, it creates a Tic Tac Toe board.

The Display class manages printing output to the command line for the user to see. In relation to the user story, the user can see the initial board.