2012-10-11 74 views
0

我正在開發一個Web服務(在Ruby中),它需要爲其接收的每條消息做許多不同的事情。如何實現複雜的消息驗證/處理流程

之前我的web服務可以處理郵件,必須做不同的事情:

  • 消毒的(例如,刪除HTML/JS)
  • 檢查格式(例如有效的電子郵件提供?)
  • 檢查IP黑名單
  • 調用第三方web服務
  • 10-30加其他東西

我在考慮實現一個過濾器/複合過濾器體系結構 ,其中每個步驟/階段都是一個過濾器。舉例來說,我能有這些過濾器

  • 清理輸入濾波器
  • 郵件過濾器
  • 國家代碼過濾
  • 黑名單過濾

每個過濾器應該能夠拒絕的消息,所以我正在考慮 過濾器應該引發/拋出異常。

這將提供很大的靈活性,並希望有一個易於理解的代碼庫 。

你會怎麼做到這一點?以上設計有什麼優點和缺點?

回答

1

如果過濾器本身實際崩潰(例如,黑名單不可用等),並且通過true/false返回值指示有效/無效狀態,或者如您所建議的,拋出一個標記,我將離開例外。

如果你不想停在第一次失敗,但無論如何,執行所有的過濾器,你應該選擇布爾返回類型和相合在一起(success &= next_filter(msg)

如果我理解正確你的情況,過濾器都修改消息或檢查其他來源的有效性(例如黑名單)。

所以我會做這樣的:

module MessageFilters 

    EmailValidator = ->(msg) do 
    throw :failure unless msg.txt =~ /@/ 
    end 

    HTMLSanitizer = ->(msg) do 
    # this filter only modifies message, doesn't throw anything 
    # msg.text.remove_all_html! 
    end 
end 

class Message 

    attr_accessor :filters 
    def initialize 
    @filters = [] 
    end 

    def execute_filters! 
    begin 
     catch(:failure) do 
     filters.each{|f| f.call self} 
     true # if all filters pass, this is returned, else nil 
     end 
    rescue => e 
     # Handle filter errors 
    end 
    end 
end 

message = Message.new 

message.filters << MessageFilters::EmailValidator 
message.filters << MessageFilters::HTMLSanitizer 

success = message.execute_filters! # returns either true or nil 
+0

謝謝,這是相當多我一直在尋找。我正在考慮解耦消息和過濾器,而是有一個複合過濾器。再次感謝「驗證」我的想法:) – Parnas