2016-06-30 4 views
0

私は、条件が条件に依存する複数の同時条件を持っています。私はこの問題に対処するための複数のアプローチを考え出しました。私は準備したいくつかのソリューションの中から最良のソリューションを選択するのに役立つ必要があります。考慮すべき事項は、パフォーマンス、再利用性、可読性、メモリー消費量です。複数の注文依存条件をどのように扱うべきですか?

アプローチ1:オブジェクトレジストリに格納タイプおよびパラメータ試験

detect2: function(subject, target){ 
     // object registry and place switch 
     var shapes = {}; 
     shapes[subject.type] = subject; 
     shapes[target.type] = target; 

     var shape1 = subject; 
     var shape2 = target; 

     var reverseShapeOrder = function() { 
      shape2 = target; 
      shape1 = subject; 
     }; 

     if (shapes.rectangle && shapes.ellipse) { 
      if (subject.type === 'ellipse') { 
       reverseShapeOrder(); 
       return this.rectWithEllipse(shape1, shape2); 
      } 
     } 
    }, 

アプローチ3に基づいて順序を切り替える:

var collision = { 
    detect1: function(subject, target){ 
     // multiple switch cases 
     var shapes = {}; 
     shapes[subject.type] = subject; 
     shapes[target.type] = target; 

     switch(subject.type) { 
      case 'rectangle': 
       switch(target.type) { 
        case 'ellipse': 
         return this.rectWithEllipse(subject, target); 
       } 
       break; 
      case 'ellipse': 
       switch(target.type) { 
        case 'rectangle': 
         return this.rectWithEllipse(target, subject); 
       } 
     } 
    }, 

アプローチ2の複数のネストされたスイッチケースを定義する文字列にタイプを連結orderOfテストに基づいて注文を切り替えます。

detect3: function(subject, target) { 
     // string concat and decoding with place switch 
     var shapeString = subject.type + target.type; 

     var rectIndex = shapeString.indexOf('rectangle'); 
     var ellipseIndex = shapeString.indexOf('ellipse'); 
     var pointIndex = shapeString.indexOf('point'); 

     var shape1 = subject; 
     var shape2 = target; 

     var reverseShapeOrder = function() { 
      shape2 = target; 
      shape1 = subject; 
     }; 

     if (rectIndex && ellipseIndex) { 
      if (ellipseIndex < rectIndex) { 
       reverseShapeOrder(); 
      } 
      return this.rectWithEllipse(shape1, shape2); 
     } 
    }, 

アプローチ4:標準的な従来のif-else文

// traditional logic 
    detect4: function(subject, target) { 
     if (subject.type === 'rectangle' && target.type === 'ellipse') { 
      return this.rectWithEllipse(subject, target); 
     } 
     else if (subject.type ==='ellipse' && target.type === 'rectangle') { 
      return this.rectWithEllipse(target, subject); 
     } 
    }, 
    rectWithEllipse: function(rect, ellipse) { 
     return false; 
    } 
}; 

アプローチ5:参照機能を有するフライセレクタを

(おかげオンザフライセレクタ提案@Bergi用)
detect5: function(subject, target) { 
     return this[subject.type + '_with_' + target.type](subject, target); 
    }, 
    rect_with_ellipse: function(rect, ellipse) { 
     return false; 
    }, 
    ellipse_with_rect: function(rect, ellipse) { 
     this.rect_with_ellipse(ellipse, rect); 
    } 
}; 

最高のソリューションを選択して、なぜそれが最適であるか理解してください。次のように

rectWithPoint: function(rect, point) { 
    return false; 
}, 
rectWithEllipse: function(rect, ellipse) { 
    return false; 
}, 
rectWithRect: function(rect, rect) { 
    return false; 
}, 
ellipseWithPoint: function(ellipse, point) { 
    return false; 
}, 
ellipseWithEllipse: function(ellipse, ellipse) { 
    return false; 
} 
+0

アプローチのおかげ

は、組み合わせの完全なリストは、それほどのように大きくなることに留意してください5:ちょうど 'this [subject.type +] '+ target.type](ターゲット、件名)'(おそらく名前をつけて)を呼んでください – Bergi

+0

サイド質問:このコードはそのまま使用するか、 Google Closure Compilerなどのツールを使用していますか? – Arnauld

+0

コードは現時点でそのまま使用されます。しかし結局私はすべてのコードをもちろんコンパイルしたいと思うでしょう。 @Arnauld – yosefrow

答えて

3

私は拡張することが容易になりますこれは、マッピングを定義します:

targets: { 
    rectangle: { 
    point: function rectWithPoint(rect, point) { 
     return false; 
    }, 
    ellipse: function rectWithEllipse(rect, ellipse) { 
     return false; 
    }, 
    rectangle: function rectWithRect(rectLhs, rectRhs) { 
     return false; 
    } 
    }, 
    ellipse: { 
    point: function ellipseWithPoint(ellipse, point) { 
     return false; 
    }, 
    ellipse: function ellipseWithEllipse(ellipseLhs, ellipseRhs) { 
     return false; 
    } 
    } 
}, 

detect5: function (subject, target) { 
    var tmp, candidates = this.targets[subject]; 

    if (!candidates) { 
    tmp = subject; 
    subject = target; 
    target = tmp; 
    candidates = this.targets[subject]; 
    } 

    if (candidates && candidates.hasOwnProperty(target)) { 
    return candidates[target].call(this, subject, target); 
    } 

    return false; 
} 
+0

これは私が考えていなかった興味深いアプローチです。私はそれを考慮するために少し時間を取るつもりです。他のものよりもこのアプローチの短所と利点は何ですか? – yosefrow

+1

新しい衝突検出器を追加するには、(subject - > target) - >述語という1組のキーを定義する必要があります。これにより、より多くのシェイプをサポートするように、コードをDRYで簡潔かつ簡潔に保ちます。これは単純な種類のグラフをモデリングする一般的なアプローチです。 – Dylon

+0

さらに、私はこれが遠く離れた最も読みやすいアプローチだと言っています –

関連する問題