2012-04-27 5 views
3

以下にGeneric Rangeクラスを示します。これは、Rangeを保存し、その後、要求されたときに、指定された値が範囲内にある場合に指定(ブール値)することを目的としています。この(汎用範囲クラス)条件ロジックを多態性に置き換える必要がありますか?はいの場合は、なぜですか?

私は「Replace Conditional with Polymorphism

を言う複数の投稿、質問、ブログなどに私の質問を読んだことがある、それは各クラスが文字通り1行のコードを持つことになり、複数のクラスに出て、コードを分離し、本当に価値があります。うまくいけば、以下のコードは私が意味するものを表示します。

クラスは2つ以上のクラスに依存していますが、ここには示されていませんが、誰かが必要な場合は後でそれを組み込むことができます。

namespace Common.Utilities 
{ 
    public class GenericRange<T> 
     where T : struct, IComparable<T> 
    { 
     #region Properties 
     public T Min { get; private set; } 
     public T Max { get; private set; } 
     public GenericRangeType RangeType { get; private set; } 
     #endregion 

     #region Constructors 
     public GenericRange(T min, T max, GenericRangeType rangeType = GenericRangeType.Inclusive) 
     { 
     // Check Parameters 
     Min = min; 
     Max = max; 
     RangeType = rangeType; 
     } 
     #endregion 

     #region Methods 
     #region Private 
     private bool IsInclusive(T value) 
     { 
     return value.IsGreaterThanOrEqualTo(Min) && value.IsLessThanOrEqualTo(Max); 
     } 

     private bool IsInclusiveMin(T value) 
     { 
     return value.IsGreaterThanOrEqualTo(Min) && value.IsLessThan(Max); 
     } 

     private bool IsInclusiveMax(T value) 
     { 
     return value.IsGreaterThan(Min) && value.IsLessThanOrEqualTo(Max); 
     } 

     private bool IsExclusive(T value) 
     { 
     return value.IsGreaterThan(Min) && value.IsLessThan(Max); 
     } 
     #endregion 

     #region Public 
     public bool Contains(T value) 
     { 
     switch (RangeType) 
     { 
      case GenericRangeType.Inclusive: return IsInclusive(value); 
      case GenericRangeType.InclusiveMin: return IsInclusiveMin(value); 
      case GenericRangeType.InclusiveMax: return IsInclusiveMax(value); 
      case GenericRangeType.Exclusive: return IsExclusive(value); 
      default: throw new NotImplementedException(); 
     } 
     } 

     public override string ToString() 
     { 
     return String.Format("Min: {0}, Max: {1}, Type: {2}", Min, Max, RangeType); 
     } 
     #endregion 
     #endregion 
    } 
} 

唯一のパブリックメソッドは、ContainとToStringです。 多態性によって正しく理解できれば、各comparisson型ごとに個別の具象クラスを作成してから、仮想メソッドを作成する必要があります。

私が理解しようとしている主なことは、利点/利点は何でしょうか?

この質問に間違った場所がある場合は、申し訳ありません。私に知らせて、私はそれを動かすでしょう。

EDIT 1:誰もがそれを必要とする場合 追加のコードは、これが完全なものにする:

public static class ComparableExtensions 
{ 
    public static bool IsEqualTo<T>(this T leftHand, T value) where T : IComparable<T> 
    { 
     return leftHand.CompareTo(value) == 0; 
    } 

    public static bool IsGreaterThan<T>(this T leftHand, T value) where T : IComparable<T> 
    { 
     return leftHand.CompareTo(value) > 0; 
    } 
    public static bool IsGreaterThanOrEqualTo<T>(this T leftHand, T value) where T : IComparable<T> 
    { 
     return leftHand.CompareTo(value) >= 0; 
    } 

    public static bool IsLessThan<T>(this T leftHand, T value) where T : IComparable<T> 
    { 
     return leftHand.CompareTo(value) < 0; 
    } 
    public static bool IsLessThanOrEqualTo<T>(this T leftHand, T value) where T : IComparable<T> 
    { 
     return leftHand.CompareTo(value) <= 0; 
    } 
} 

public enum GenericRangeType 
{ 
    Inclusive, 
    Exclusive, 
    InclusiveMin, 
    InclusiveMax 
} 

答えて

1

異なるクラスに出て、それを破るには、既存のコードを変更せずに含まれて拡張できます。この場合、ここに含まれているすべての基底をカバーしているのであまり意味がありませんが、拡張性が非常に有用な場合もあります。

1

IMO - 古典的なOOPS用語の純粋に基本クラスではなく、もっと "テンプレート"クラスであるジェネリックを使用しました。

この場合
public class GenericRange{...} 

public class IntRange : GenericRange{...} 
public class DecimalRange : GenericRange{...} 

、それは本当にオーバーライドされたメソッドとして別のサブタイプに含まれての実装を抜け出すために理にかなって:私が言うことを意味何

はあなたのように記述されたクラスを持っていた場合、あります。

しかし、コードテンプレートを使用しているので、テンプレートクラスを初期化する方法に依存する多態的な動作の利点があります。

あなたがやったのであれば、:

new GenericRange<int>(1, 100, inclusive); 
new GenericRange<decimal>(1.0, 100.0, inclusive); 

をあなたはすでにそれはあなたがそのようなコードをテンプレートではなく、特殊なサブクラスを持つことができますように私は、ジェネリックの大きなメリットとして、これを参照してください、多形性行動が行われています前に示したように。

1

将来的には大幅に拡張する必要がないかぎり、他のアセンブリでも拡張できるパブリッククラスである必要はありません。多少の柔軟性が必要な場合は、多態性を使用するか、Func<T, bool>()を作成することができます。具体的には、Containsメソッドを公開するだけで、Funcを使用して実装されているわけではありません。 RangeTypeが設定されています。その後、Containsメソッドはreturn myFunc(value);になります。

+0

Func、Anonymous、Expressions、Delegatesは分かりません。これは多かれ少なかれデリゲートを宣言していますか?私はデリゲートを宣言することから始めましたが、多くの利点は見られませんでした。 Funcの小さなサンプルを使って、より良い説明をしてくれますか? –

関連する問題