春季促销
状态

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

状态在其他编程语言中的实现

C# 状态模式讲解和代码示例 C++ 状态模式讲解和代码示例 Go 状态模式讲解和代码示例 Java 状态模式讲解和代码示例 PHP 状态模式讲解和代码示例 Python 状态模式讲解和代码示例 Rust 状态模式讲解和代码示例 Swift 状态模式讲解和代码示例 TypeScript 状态模式讲解和代码示例