L’État est un patron de conception comportemental qui permet à un objet de modifier son comportement lorsque son état interne change.
Ce patron extrait les comportements liés aux états dans des classes séparées et force l’objet original à déléguer les tâches à une instance de ces classes, au lieu de le faire lui-même.
Complexité :
Popularité :
Exemples d’utilisation : L’état est souvent utilisé en Ruby pour convertir de gros switch
(automates finis) en objets.
Identification : L’état peut être reconnu grâce à des méthodes contrôlées depuis l’extérieur, qui modifient leur comportement en fonction de l’état des objets.
Exemple conceptuel
Dans cet exemple, nous allons voir la structure de l’État . Nous allons répondre aux questions suivantes :
Que contiennent les classes ?
Quels rôles jouent-elles ?
Comment les éléments du patron sont-ils reliés ?
main.rb: Exemple conceptuel
# The Context defines the interface of interest to clients. It also maintains a
# reference to an instance of a State subclass, which represents the current
# state of the Context.
class Context
# A reference to the current state of the Context.
attr_accessor :state
private :state
# @param [State] state
def initialize(state)
transition_to(state)
end
# The Context allows changing the State object at runtime.
def transition_to(state)
puts "Context: Transition to #{state.class}"
@state = state
@state.context = self
end
# The Context delegates part of its behavior to the current State object.
def request1
@state.handle1
end
def request2
@state.handle2
end
end
# The base State class declares methods that all Concrete State should implement
# and also provides a backreference to the Context object, associated with the
# State. This backreference can be used by States to transition the Context to
# another State.
class State
attr_accessor :context
# @abstract
def handle1
raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
end
# @abstract
def handle2
raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
end
end
# Concrete States implement various behaviors, associated with a state of the
# Context.
class ConcreteStateA < State
def handle1
puts 'ConcreteStateA handles request1.'
puts 'ConcreteStateA wants to change the state of the context.'
@context.transition_to(ConcreteStateB.new)
end
def handle2
puts 'ConcreteStateA handles request2.'
end
end
class ConcreteStateB < State
def handle1
puts 'ConcreteStateB handles request1.'
end
def handle2
puts 'ConcreteStateB handles request2.'
puts 'ConcreteStateB wants to change the state of the context.'
@context.transition_to(ConcreteStateA.new)
end
end
# The client code.
context = Context.new(ConcreteStateA.new)
context.request1
context.request2
output.txt: Résultat de l’exécution
Context: Transition to ConcreteStateA
ConcreteStateA handles request1.
ConcreteStateA wants to change the state of the context.
Context: Transition to ConcreteStateB
ConcreteStateB handles request2.
ConcreteStateB wants to change the state of the context.
Context: Transition to ConcreteStateA
État dans les autres langues