repeatIterator

Iterator

The Command Pattern is a behavioral design pattern where an object is used to encapsulate all the information needed to perform an action. This pattern allows you to decouple sender and receiver objects, providing a more flexible and extensible design.

Real World Example

Imagine your favorite song list. You can add new songs to it, delete songs, rewind and much more. Let’s try to create such a list of songs using the Iterator pattern.
Before we create our playlist, we’re going to need songs.

class Song
  attr_reader :name

  def initialize(name)
    @name = name
  end
end
With the Song class created, we can finally create some songs.

imagine = Song.new('Imagine')
hey_jude = Song.new('Hey Jude')
baby = Song.new('Baby')
The next step will be to create your own playlist that will store our songs. Of course, we also need to add a method to it that will allow them to be added.

class Playlist
  attr_reader :songs

  def initialize
    @songs = songs
  end

  def add_song(song)
    songs << song
  end
end

class Playlist
  attr_reader :songs

  def initialize
    @songs = songs
  end

  def add_song(song)
    songs << song
  end
end
At this point, we’ve created a class that allows us to add songs, so let’s add the previously created songs to it.

favourties = Playlist.new

favourites.add_song(imagine)
favourites.add_song(hey_jude)
favourites.add_song(baby)

favourites.songs.size => 3
A class that is only a container for other objects is of little use to us. The purpose of an Iterator is to store and manage aggregated objects. So let’s add methods that will allow us to scroll through songs and check which one is up to date.

class Playlist
  attr_reader :index, :songs

  def initialize
    @songs = songs
    @index = 0
  end
  
  def next
    # Start again if this is the last song
    last_song? ? index = 0 : index += 1
  end

  def previous
    # Go to the end if this is the first song
    first_song? ? index = songs.size : index -= 1
  end
  
  def current_song
    songs[index]
  end

  def add_song(song)
    songs << song
  end

  private

  def last_song?
    index < songs.length
  end

  def first_song?
    index == 0
  end
end
The class constructed in this way allows us to manage our playlist. We could also easily add more methods that would allow us, for example, to delete songs or change the mode for random songs.