The State Pattern

If you have an object whose behaviour depends on one of several states, you may end up with several very similar conditionals sprinkled throughout the class.

The State Pattern provides a mechanism for removing this duplicate conditional code by maintaining a reference to an object referencing the current state and delegating state-specific behaviour to that object.

class TCPConnection
  attr_accessor :state

  def initialize
    @state = TCPClosed.instance
  end

  def open
    @state.open(self)
  end

  def close
    @state.close(self)
  end
end

class TCPClosed
  def open(connection)
    connection.state = TCPOpen.instance
  end

  def close(connection); end
end

class TCPOpen
  def open(connection); end

  def close(connection)
    connection.state = TCPClosed.instance
  end
end