0

私は(Rubyで)Webサービスを開発しています。このサービスは、受信するメッセージごとにさまざまなことを行う必要があります。

私のWebサービスがメッセージを処理する前に、さまざまなことを行う必要があります。

  • サニタイズ(例:HTML / JSの削除)
  • フォーマットを確認してください(例:有効なメールアドレスが提供されていますか?)
  • ブラックリストのIPを確認してください
  • サードパーティのWebサービスを呼び出す
  • プラス10-30他のもの

各ステップ/フェーズがフィルターであるフィルター/複合フィルターアーキテクチャーの実装を考えています。たとえば、私はこれらのフィルターを持つことができます

  • 入力フィルターをサニタイズする
  • メールフィルター
  • 国コードフィルター
  • ブラックリストフィルター

各フィルターはメッセージを拒否できるはずなので、フィルターは例外を発生/スローする必要があると考えています。

これにより、多くの柔軟性が得られ、できれば理解しやすいコードベースが得られます。

どのようにこれをしましたか?そして、上記のデザインの長所と短所は何ですか?

4

1 に答える 1

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
于 2012-10-11T14:48:59.983 に答える