如何实现复杂的消息验证/处理流程

时间:2012-10-11 12:41:37

标签: ruby design-patterns architecture business-logic

我正在开发一个需要做很多事情的Web服务(在Ruby中) 收到的每封邮件都有不同的内容。

在我的网络服务处理消息之前,它必须做不同的事情:

  • 清理(例如删除HTML / JS)
  • 检查格式(例如提供有效的电子邮件?)
  • 检查黑名单中的IP
  • 调用第三方Web服务
  • 加上其他10-30件事

我正在考虑实施过滤器/复合过滤器架构 其中每个步骤/阶段都是一个过滤器。例如,我可以使用这些过滤器

  • 清理输入过滤器
  • 电子邮件过滤器
  • 国家/地区代码过滤器
  • 黑名单过滤器

每个过滤器都应该可以拒绝消息,所以我正在考虑 过滤器应该引发/抛出异常。

这将提供很多灵活性,并希望是一个代码库 容易理解。

你会怎么做?以上设计的优点和缺点是什么?

1 个答案:

答案 0 :(得分: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