markdown Ruby中的状态模式示例

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了markdown Ruby中的状态模式示例相关的知识,希望对你有一定的参考价值。

class Document
  attr_reader :state, :current_user

  def initialize
    @state = DraftState.new(self)
    @current_user = User.new('admin')
  end

  def set_state(new_state)
    @state = new_state
  end

  def publish
    @state.publish
  end

  def unpublish
    @state.unpublish
  end

  User = Struct.new(:role)
end

class State
  attr_reader :context

  def initialize(context)
    @context = context
  end

  def publish
    raise NotImplementedError
  end

  def unpublish
    raise NotImplementedError
  end
end

class DraftState < State
  def publish
    next_state = ReviewState.new(context)
    context.set_state(next_state)
    next_state.to_s
  end

  def to_s
    'draft'
  end
end

class ReviewState < State
  def publish
    if context.current_user.role == 'admin'
      next_state = PublishedState.new(context)
      context.set_state(next_state)
      next_state.to_s
    else
      "Admin must review."
    end
  end

  def unpublish
    next_state = DraftState.new(context)
    context.set_state(next_state)
    next_state.to_s
  end

  def to_s
    'under review'
  end
end

class PublishedState < State
  def unpublish
    next_state = DraftState.new(context)
    context.set_state(next_state)
    next_state.to_s
  end

  def to_s
    'published'
  end
end
# State Pattern Example in Ruby

> The State pattern suggests to create new classes for all possible states of a context object and to extract the state-related behaviors into these classes.
The context will contain a reference to a state object that represents its current state. Instead of performing a behavior on its own, the context will delegate the execution to a state object.
To change the context's state, one would pass another state object to the context. But to make states interchangeable, all states classes must follow the common interface, and the context must communicate with its state object via that interface.
The described structure may look like the Strategy pattern, but there is one key difference. In the State pattern, the context, as wells as particular states, can initiate the transitions from one state to another.

Read more about the State Pattern here: https://refactoring.guru/design-patterns/state

## Example Usage
```
$ ⇒  pry
[1] pry(main)> require './state_pattern.rb'
=> true

[2] pry(main)> document = Document.new
=> #<Document:0x007f98b6a44470 @current_user=#<struct Document::User role="admin"> ...>>>

[3] pry(main)> document.publish
=> "under review"
[4] pry(main)> document.unpublish
=> "draft"

[5] pry(main)> document.publish
=> "under review"
[6] pry(main)> document.publish
=> "published"
[7] pry(main)> document.publish
NotImplementedError: NotImplementedError

[8] pry(main)> document.unpublish
=> "draft"
```

If the `context.current_user.role != "admin"`
```
[6] pry(main)> document.publish
=> "Admin must review."

[7] pry(main)> document.unpublish
=> "draft"
[8] pry(main)> document.publish
=> "under review"
[9] pry(main)> document.publish
=> "Admin must review."
```

以上是关于markdown Ruby中的状态模式示例的主要内容,如果未能解决你的问题,请参考以下文章

markdown Rails任务(Ruby中的学生注册).md

ruby RubyOnRails测试反模式 - 示例

ruby 状态模式灯泡

markdown 列表交叉合并类似Python中的zip功能(clojure clj ruby​​ scala map vector list)

ruby ruby中的示例链表

Ruby 示例中的 DCI 中的 Thread.current 是啥?