0

私はジェネリックVector<T>クラスとジェネリックMatrix<T>クラスを持っていますが、両方のクラスにインターフェイスを実装させるのは良い考えではないかと思いました。

基本的に、私は2つのアルゴリズムを実装しています。AlgorithmAとAlgorithmBは、どちらも非常によく似た操作(リセット、平均など)を実行しますが、アルゴリズムが異なり、異なる構造で AlgorithmA動作Vector<double>AlgorithmBますMatrix<Complex>

私がこれまでに持っているデザイン:

abstract class AlgorithmArray
{
   // Operator overloading
}

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

    // Overrides
}

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

     // Overrides
}

(抽象クラ​​スの代わりに)インターフェース' 'AlgorithmAArrayから派生し、それを実装したいと思います。とにかく、これらのアルゴリズムは、2つの場所間の送受信をシミュレートするために使用されます。Vector<T>IAlgorithmArray

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

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

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

        }
}

私の問題に取り組むためのより良い方法はありますか?

注:基本クラスAlgorithmArrayは、演算子/クローン作成などのメソッドの多くを複製します。おそらくジェネリックを使用して、これを回避できると思いますか?

ありがとう !

4

2 に答える 2

1

任意のデータ構造をパラメーターとして受け取り、それらの処理を実行できる2つのアルゴリズムクラスを作成することをお勧めします。このすべてのOOP継承の必要性はわかりません。それは、複雑さを増すだけです。

于 2012-04-22T16:12:42.690 に答える
1

インターフェイスを使用すると、ベクトル/行列の読み取りまたは書き込みのみを行うルーチンが、予想されるベクトル/行列タイプのサブタイプまたはスーパータイプのベクトル/行列を受け入れることができます。これが一般的に行列で役立つかどうかはわかりませんが、ベクトルのアプリケーションによっては便利な場合があります。

クラスに対するインターフェースのもう1つの利点は、状況により適している可能性があり、可変、不変、およびコピーオンライトオブジェクト間のスムーズな相互運用を可能にすることです(後者は追加レベルの間接参照を必要とします)。これは、相互にコピーされるベクトルまたは行列がたくさんある場合に役立ちますが、そのうちのいくつかは最終的に変更されます。メソッドAsImmutable、、、AsNewMutableおよびAsPossiblyExistingMutableそのために役立つことができます。最初のメソッド(可変オブジェクトで呼び出された場合)は、呼び出し時のサブジェクトの内容と一致する新しい不変オブジェクトを作成するか、(不変で呼び出された場合)オブジェクトを単にそのサブジェクトを返します。2つ目は、既存のオブジェクトが可変であるか不変であるかに関係なく、新しい可変オブジェクトを作成します。3番目のメソッドは、可変の場合はそのサブジェクトを返すか、そうでない場合は新しい可変オブジェクトを作成します。これは通常、オブジェクトの所有者が、オブジェクトが可変である場合に唯一の参照を保持していることを知っている場合にのみ使用する必要があります。

たとえば、_thingタイプのプライベートフィールドがある場合IReadableVector<Foo>、セッターはそれをに設定しvalue.AsImmutable()、ゲッターはを返すことができ_thing.AsImmutable()ます。私のミューテーションメソッドは_thing = _thing.AsPossiblyExistingMutable()、ミューティングメソッドを呼び出す前に設定されます。受け取ってから変更を試みていない場合_thing、それは不変のオブジェクトになります(他のオブジェクトも参照を保持している可能性があります)。初めて変更すると、新しい変更可能なオブジェクトにコピーされます。ただし、後続のミューテーションでは、外部コードにさらされることはないため、同じミュータブルオブジェクトを使用し続ける可能性があります。

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

于 2012-04-23T16:09:02.253 に答える