2012-04-27 14 views
3

次のようにしたいので、私は実際にそれを設計する方法に関するアドバイスを探しています。私は、特定のエンティティタイプ上で実行することができますFilterSymfony2 Doctrine2フィルタとルールのための適切なエンティティの設計

  • Filter sが自分のルールを使用して、彼らの行動を定義するRule
  • Filterのプロセスエンティティを持っている、とブール
  • Asを返してきた

    • 与えられたフィールドの正規表現が拒否され、ルールを定義することができるというフィルタを適用する具体的な例です。私は同じフィルターで簡単なプレフィックスマッチングを使う違う規則を持つこともできます。

  • は、だから私はその後、私はする予定次

    interface FilterInterface 
    { 
        /** 
        * Load the rules for this filter 
        */ 
        function loadRules(); 
    
        /** 
        * Filter an entity in an optional context 
        * @param mixed $entity Should return true for $this->supportsEntity($entity) 
        * @param array $context Other information 
        * 
        * @return boolean True if the $entity passes this filter 
        */ 
        function filter($entity, $context = array()); 
    
        /** 
        * Check if filter supports the entity type 
        * @param mixed $entity 
        * 
        * @return boolean true if this Filter can be run for that entity type 
        */ 
        function supportsEntity($entity); 
    } 
    

    を作ってみた:データベースからルールをロードし、フィルタを実装します

    class ImageFilter implements FilterInterface 
    

    だから最初Iしかし

    FilterRuleようなエンティティを有する:

  • タイプ(これを使用するフィルタを定義する列挙型)

    • 範囲(同様に、ルールの異なるタイプを持つことができ正規表現と前に述べた接頭辞)
    • 値(文字列はルールの種類によって異なる)

    ImageFilterは、FilterRuleをロードします。スコープは、一定の定数に設定されています。その後、ImageFilterは、フィルタのタイプをチェックし、それを次々にエンティティに適用するという重い作業を行います。次のコードはこれを示しています。

    public function filter($entity) 
    { 
        foreach ($this->rules as $rule) { 
         switch($rule->getType()) { 
          case RULE_TYPE_REGEX: 
           $this->doRegex(); 
          break; 
          case RULE_TYPE_PREFIX: 
           $this->doPrefix(); 
          break; 
         } 
        } 
    } 
    

    しかし、私は、企業が上記switchブロックを担当する必要があり、疑問に思いましたか?新しいルールとどのように限り、「スコープ」は正しいようにそれらを処理するために気にしない

    public function filter($entity) 
    { 
        foreach ($this->rules as $rule) { 
         $rule->process($entity); 
        } 
    } 
    

    これは私には思えるクリーナー、Filter:だからそれは次のようになります。 しかし、エンティティはシンプルなPOPOでなければならないという印象を受けました。この種のロジックが悪いパターンであるように思われます(しかし、エンティティが本当にやるべきことを100%確信できませんでした)。

    私もと考えていたので、それぞれRule "type"は別のクラスになる可能性があり、ロジックはかなりシンプルになりました。最後に、別のタイプのRuleが、何らかの形で実際の作業を行う「動作」や何かを使用する必要があるかもしれないと考えていました。そこでここでは、まとめての

    は私の現在の考えです:

    1. Filterは、すべての作業がRuleの種類を確認し、それに従って行動しません。 Ruleはいくつかの文字列を保持する単なる "ダム"エンティティです
    2. Rule与えられたエンティティに対して独自の型をチェックして何かを行うすべての作業を行います。今Ruleエンティティは、ビット「太っ」であるが、それはFilterFilterから実装が新しいRuleタイプ
    3. Rule、上記を行うために、継承を使用しない効果的に同じ考えが、switchこれ以上を追加して変更する必要はありません非表示になります声明
    4. 2.または3.しかしRuleどちらかがタイプごとに異なる「行動」のオブジェクトをインスタンス化し(実際に依存性の注入を使用していないことは悪いと思われる、振る舞いをカプセル化するかの良いデザインのように思える)
    5. 1と4を組み合わせます。したがって、FilterRuleから適切な動作を得ることができます(依存関係注入を使用できるようになりましたイオンは「行動」工場のように)

    私はそれについてもっと考えていると思いますが、この分野のベストプラクティスはわかりません。私はこれが比較的一般的な例であると確信していますので、どの方向へ進むべきかについていくつかの情報を得たいと考えています。 RulesFiltersRuleProcessing - 私はあなたがここに与えた説明から何を得る

  • +0

    それはあなたが扱っているドメインに関するいくつかのより多くの情報を入力しないで答えを与えるには少し難しいですと。あなたが解決しようとしている実際の問題について、聴衆にもっと教えてください。 –

    答えて

    0

    (うまくいけば、それは答えるのに十分な完全だ、このような長い質問申し訳ありませんが)あなたは、3つの異なるものを持っているということです。だから、私は3つの別々のものを保つだろう。

    Rulesは、フィルタの動作を定義することになります。

    Filtersは、ルールの読み込みやその他のチェックを行います。

    $entity$ruleと処理された結果を返すように、それぞれRule Processingを保持します。だから、あなたはこのようなものでしょう:

    public function filter($entity) 
    { 
        foreach ($this->rules as $rule) { 
         RuleProcessing->processRule($entity, $rule); 
        } 
    } 
    

    を(私の理解はここに正しくない場合、私に教えてください。)

    関連する問題