State

  • object behavioral pattern

GoF definition (p. 305):

Allow an object to alter its behavior when its internal state changes. The object will appear to change its class.

The crux of this pattern is to encapsulate the state and state-related behaviors of an object within another object. This mitigates the need for complicated control-flow based on state, and delegates state-specific behaviors to the state object. Very similar to the Strategy pattern in this respect.

Either the parent object or the state object can determine which state succeeds another.

Pros:

  • Encapsulates state and state-specific behavior within an internal and interchangeable object.
  • Eliminates the need for complicated control-flow based on state.
  • Prevents inconsistent or contradictory states by delegating state to a single object instance (thereby making state 'atomic').

Example

Context

  • parent object, maintains an instance of state object
class Car
  attr_accessor :state

  def initialize
    @state = Neutral.new
  end

  def throttle
    @state.throttle
  end

  def brake
    @state.brake
  end

  # We also delegate state transitions to the state object:

  def shift_up
    @state.shift_up(self)
  end

  def shift_down
    @state.shift_down(self)
  end
end

State

  • contains the context's state and state-related behaviors
class CarState
  def throttle
    raise NotImplementedError
  end

  def brake
    raise NotImplementedError
  end

  def shift_up(car)
    raise NotImplementedError
  end

  def shift_down(car)
    raise NotImplementedError
  end
end

class Neutral < CarState
  def throttle
    puts "The engine revs loudly but you remain motionless."
  end

  def brake
    puts "Your brake lights flash on. Nothing else happens."
  end

  def shift_up(car)
    puts "You shift into drive."
    car.state = Drive.new
  end

  def shift_down(car)
    puts "You are already in neutral."
    car.state = self
  end
end

class Drive < CarState
  def throttle
    puts "The engine revs and you begin to move forward."
  end

  def brake
    puts "You begin to slow down."
  end

  def shift_up(car)
    puts "You are already in drive."
    car.state = self
  end

  def shift_down(car)
    puts "You shift into neutral."
    car.state = Neutral.new
  end
end

Implimentation

my_saab = Car.new
my_saab.throttle
my_saab.shift_up
my_saab.throttle
my_saab.brake
my_saab.shift_down

results matching ""

    No results matching ""