我创建了一个具有已定义工作流程的引擎。消息进来,以某种方式处理,然后发送出去。现在我想让使用这个引擎的应用程序挂钩到流中并修改消息的处理。
我曾想过在应用程序中添加一个初始化程序,然后对引擎的消息处理类进行猴子补丁,但这让我觉得有点脏。
我确信有一种更明智的方式来做这样的事情。你们能帮帮我吗?
我创建了一个具有已定义工作流程的引擎。消息进来,以某种方式处理,然后发送出去。现在我想让使用这个引擎的应用程序挂钩到流中并修改消息的处理。
我曾想过在应用程序中添加一个初始化程序,然后对引擎的消息处理类进行猴子补丁,但这让我觉得有点脏。
我确信有一种更明智的方式来做这样的事情。你们能帮帮我吗?
这不是一个需要“好”答案的问题,但我将作为正确代码格式的答案发布。
这听起来很像 javascript 回调方案。我们通常在 ruby 中用块做的事情。
Monkey patching 听起来肯定不像预期的 api 那样性感,而且从用户的角度来看它总是看起来很骇人听闻。我可能会喜欢使用带块的类方法,例如:
class Foo < ActiveRecord::Base
include MyEngineConcern
on_engine_stuff do |message|
create!( name: 'hello', message: message )
end
end
然后您的引擎类可以使用它:
module MyEngineConcern
def self.included( base )
base.extend ClassMethods
end
module ClassMethods
def on_engine_stuff( &callback )
MyEngine::Callbacks.add callback
end
end
end
module MyEngine
class Callbacks
class << self
@_callbacks = []
def add( callback )
@_callbacks << callback
end
def process( message )
@_callbacks.each do |callback|
message = callback.call( message )
end
message
end
end
end
end
请注意,这意味着您的引擎是由模型访问的,我们可能需要更多关于它的信息来建议正确的设计。