在ruby中制作某种事件系统

时间:2014-12-08 14:24:49

标签: ruby events alias

我有这样的代码:

module EventSystem
  @@events = {
    :on_minute_change = [],
    :on_hour_change = []
  }

  def self.register_action(event, action)
    @@events[event].push(action)
  end

  def self.notify_event(event)
    @@events[event].each do |action|
      Actions.send(action)
    end
  end
end

module Actions
  def self.make_something
    p "something is happening"
  end

  def self.make_something_else
    p "something else is happening"
  end
end

EventSystem.register_action(:on_minute_change, :make_something)
EventSystem.register_action(:on_minute_change, :make_something_else)
EventSystem.register_action(:on_hour_change, :make_something)

class Own_Time
  def next_minute
    # minute += 1
    EventSystem.notify_event(:on_minute_change)
  end

  def next_hour
    # hour += 1
    EventSystem.notify_event(:on_hour_change)
  end
end

@own_time = Own_Time.new

@own_time.next_minute
@own_time.next_minute
@own_time.next_hour

输出:

"something is happening"
"something else is happening"

"something is happening"
"something else is happening"

"something is happening"

所有这一切的原因是,我希望有一个基本代码并添加新的可选插件 保持模块化和可变性的基础。我也可以使用例如别名next_minute方法,而不是具有将调用所有已注册方法的事件。但是因为我会有很多插件,这意味着我将不得不使用许多别名,所以我想到了一种更简单的方法。

现在我想知道我的方法是否正常,或者我的代码是否存在一些漏洞和问题。 任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:1)

在我看来,你正试图重新创建一个已经很好理解的设计模式Observer Pattern。 Ruby标准库已经有一个模块可以帮助您实现这一目标。记录here。我在下面给出了一个示例,但文档中的示例更加全面。免责声明:它已经迟到了,所以如果我完全误解你的问题我会道歉。

class Timer
  include Observable

  def run
    # TODO: add code to check time here
    # TODO: check whether minute or hours have changed here

    # call this when minute is changed
    change 

    # notify the objects observing the timer and call
    # the method that you want to trigger
    # NOTE: you can pass in args here that might need
    # to be passed into the method on the receiving
    # observer
    notify_observers(args)
  end
end

class ExampleMaker
  def make_something(args)
    # do something with args
  end
end

timer = Timer.new
maker = ExampleMaker.new
timer.add_observer(maker, :make_something)