
Ruby 状态模式讲解和代码示例
状态是一种行为设计模式, 让你能在一个对象的内部状态变化时改变其行为。
该模式将与状态相关的行为抽取到独立的状态类中, 让原对象将工作委派给这些类的实例, 而不是自行进行处理。
复杂度:
流行度:
使用示例: 在 Ruby 语言中, 状态模式通常被用于将基于 switch
语句的大型状态机转换为对象。
识别方法: 状态模式可通过受外部控制且能根据对象状态改变行为的方法来识别。
概念示例
本例说明了状态设计模式的结构并重点回答了下面的问题:
- 它由哪些类组成?
- 这些类扮演了哪些角色?
- 模式中的各个元素会以何种方式相互关联?
main.rb: 概念示例
# 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: 执行结果
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