2012-04-22 9 views
0

私はgeneric Vector<T>クラスとgeneric Matrix<T>クラスを持っていて、どちらのクラスにもインターフェイスを実装させることをお勧めしますか? AlgorithmAとAlgorithmB、非常に同様の操作を行うどちらも(リセット、平均...等)の異なるアルゴリズムと異なる構造上の行為ではなく: AlgorithmAVector<double>AlgorithmBしばらくの用途を使用していますベクタークラスとマトリックスクラスのインターフェイスですか?

基本的に、私は2つのアルゴリズムを実装していますMatrix<Complex>

私がこれまで持っているデザイン:私はAlgorithmAArrayVector<T>から派生し、また、インタフェースのIAlgorithmArray '(代わりの抽象クラス)を実装していことを好むだろう

abstract class AlgorithmArray 
{ 
    // Operator overloading 
} 

class AlgorithmAArray : AlgorithmArray 
{ 
    private Vector<double> _vector; 

    // Overrides 
} 

class AlgorithmBArray : AlgorithmArray 
{ 
    private Matrix<Complex> _matrix; 

    // Overrides 
} 

。私の問題にアプローチするためのより良い方法が

public class CommunicationParameters 
{ 
     private AlgorithmArray _transmission; 
     private AlgorithmArray _receiving; 

     public void Compute() 
     { 
      if(_transmission != null) 
       _transmission.Compute(); 

      if(_receiving != null)   
       _receiving.Compute() 

     } 
} 

あります。とにかく、これらのアルゴリズムは、2つの場所の間の受信/送信をシミュレートするために使用されていますか?

注:基本クラスAlgorithmArrayは、operator/cloning ... etcメソッドの多くを複製します。これはおそらくジェネリックを使用して回避できますか?

ありがとうございます!

答えて

1

私は、任意のデータ構造をパラメータとしてとり、それらのことを行うことができる2つのアルゴリズムクラスを作成することをお勧めします。私はこのOOPのすべての継承の必要性を見ません、それは単に複雑さを追加します。

1

インタフェースでは、ベクトル/行列のみを読み取るか、または書き込むルーチンが、予想されるベクトル/行列型のサブタイプまたはスーパータイプのベクトル/行列を受け入れることができます。私はそれが一般的に行列では便利だろうとは思っていませんが、ベクトルのいくつかのアプリケーションでは便利かもしれません。

あなたの状況により適している可能性のある、クラスに対するインターフェイスのもう1つの利点は、変更可能なオブジェクト、不変オブジェクト、およびコピーオンライトオブジェクト間のスムーズな相互運用を可能にすることです(後者は、 。これは、お互いのコピーになるベクトルや行列がたくさんある場合に便利ですが、そのうちいくつかは変更されることになります。方法AsImmutable,AsNewMutableおよびAsPossiblyExistingMutableは、そのために有用であり得る。最初のメソッド(変更可能なオブジェクトで呼び出された場合)は、呼び出し時にそのサブジェクトの内容と内容が一致する新しい不変オブジェクトを作成するか、不変のオブジェクトで呼び出された場合は単にそのサブジェクトを返します。 2つ目は、既存のオブジェクトが変更可能か不変かにかかわらず、新しい可変オブジェクトを作成します。 3番目のメソッドは、変更可能な場合はそのサブジェクトを返します。そうでない場合は、新しい可変オブジェクトを作成します。一般的には、オブジェクトの所有者が、オブジェクトが変更可能であれば、それが唯一の参照を保持することを知っている場合にのみ使用されるべきである。私はタイプIReadableVector<Foo>のプライベートフィールド_thingを持っている場合

例えば、私のセッターはvalue.AsImmutable()に設定することができ、私のゲッターは_thing.AsImmutable()を返すことができます。私の突然変異のメソッドは、突然変異のメソッドを呼び出す前に_thing = _thing.AsPossiblyExistingMutable()を設定します。私が受け取ってから_thingを突然変異させようとしなかったならば、それは不変のオブジェクト(他のオブジェクトも参照を保持するかもしれない)です。私が最初に変異させると、新しい可変オブジェクトにコピーされます。しかし、それ以降の突然変異は、外部コードに晒されることはないので、同じ可変オブジェクトを使用し続けることができます。

PS - およびのみImmutableVector<T>ImmutableMatrix<T>クラスを有する対、インターフェースとしてIImmutableVector<T>IImmutableMatrix<T>を有するに対する両方の引数があります。一方で、もしそれらがインタフェースであれば、実際にすべての要素を格納する必要のない有用な実装を持つことが可能です。たとえば、を継承し、ちょうど1つのTとその長さを示す数字を含むAllMatchingVector<T>のようなクラスを持つことができます。そのインデックス付きゲッターは、指定されたインデックスに関係なく、その要素を単純に返します。DiagonalMatrix<T>は対角線の内容に対してIImmutableVector<T>を保持し、Tは他の場所に返されます。特に大きなベクトル/行列の場合、そのようなクラスはメモリを節約することができる。一方、実際には不変ではないクラスでこれらのインタフェースのどれも実装していないことを保証する方法はありません。私の個人的な気持ちは、そのためのインターフェイスを使用しても問題ないということです。結局のところ、クラスがIComparable<T>を実装していて、不変のソート関係を持たない方法でSortedDictionary<T>が失敗すると不平を言う人はほとんどいません。それにもかかわらず、多くの人々がそのような概念に同意しない。

関連する問題