2016-04-21 72 views
2

我有很多服務類,其中call方法的參數有變化。在ruby方法中定義自定義回調

我想在每個call方法的末尾調用函數notify。我不想修改這些服務類,但我願意修改基類。

我在玩ActiveSupport::Callbacks,但它沒有服務於不修改服務類的目的。

require 'active_support' 
class Base 
    include ActiveSupport::Callbacks 
    define_callbacks :notifier 

    set_callback :notifier, :after do |object| 
    notify() 
    end 

    def notify 
    puts "notified successfully" 
    end 
end 

class NewPost < Base 
    def call 
    puts "Creating new post on WordPress" 
    # run_callbacks :notifier do 
    # puts "notifying....." 
    # end 
    end 
end 

class EditPost < Base 
    def call 
    puts "Editing the post on WordPress" 
    # run_callbacks :notifier do 
    # puts "notified successfully" 
    # end 
    end 
end 

person = NewPost.new 
person.call 

問題爲了運行回調,我需要取消對註釋的代碼。但在這裏你可以看到我需要修改現有的類來添加run_callbacks塊。但那不是我想要的。我可以輕鬆地調用notify方法,而不會增加這種複雜性。

任何人都可以建議我怎麼才能達到解決方案的紅寶石方式?

回答

3

我會做這樣的事情:

require 'active_support' 
class Base 
    include ActiveSupport::Callbacks 
    define_callbacks :notifier 

    set_callback :notifier, :after do |object| 
    notify() 
    end 

    def notify 
    puts "notified successfully" 
    end 

    def call 
    run_callbacks :notifier do 
     do_call 
    end 
    end 

    def do_call 
    raise 'this should be implemented in children classes' 
    end 
end 

class NewPost < Base 
    def do_call 
    puts "Creating new post on WordPress" 
    end 
end 

person = NewPost.new 
person.call 

另一種解決方案,而不的ActiveSupport:

module Notifier 
    def call 
    super 
    puts "notified successfully" 
    end 
end 


class NewPost 
    prepend Notifier 

    def call 
    puts "Creating new post on WordPress" 
    end 
end 

NewPost.new.call 

您應該檢查你的Ruby版本prepend是一個 「新」 的方法(2.0)

+0

外貌好,但它又不能達到目的。我不想改變所有的孩子班。此外,您建議的解決方案也需要更改所有對「調用」方法的引用。 –

+1

這是在Rails中使用ActiveSupport :: Callbacks的方式......您也可以預先安裝一個通知器模塊(參見編輯答案) – ThomasSevestre

+0

Awsome。我愛第二個解決方案。謝謝 –