2

オブジェクトのリストと、リストに付随する一連のプロパティを保持する特別なオブジェクトがあります。

特別なオブジェクトのリスト部分にアイテムを挿入する機能があります。関数はリストに付随するプロパティに依存するため、プロパティとリストの両方を保持する新しいオブジェクトを作成することにしました。

質問1:関数がアイテムの挿入を開始する前に、リストがnullでないことを確認する責任は誰にありますか?

  1. 呼び出し元は新しいリストを作成して関数に渡す必要がありますか?

  2. 呼び出し先は、渡されたオブジェクトの状態に関係なく、新しいリストを作成してオブジェクトに割り当てる必要がありますか?

  3. 関数は、オブジェクトを取り込んで、オブジェクトを変更せずに新しいリストを返し、返されたリストをその特別なオブジェクトに割り当てるために呼び出し元に任せるように設計する必要がありますか?

または...私が考慮していない他のオプションはありますか?

関連する質問2:デザインにリストに付随するプロパティが必要な場合、プロパティとリストの両方を保持する新しいクラスを作成することを選択する必要がありますか、それとも追加のプロパティを保持するリストのサブクラスを作成する必要がありますか?

4

2 に答える 2

3

つまり、リストを含むオブジェクトは、概念的には、データを格納するための有効な手段を持つ責任があります。つまり、必要なときにリストをインスタンス化する責任があります。

オブジェクトがオブジェクトのコレクションを表すように設計されている場合、新しいオブジェクトが複数のタイプのコレクションの「ラッパー」になることが目的の一部でない限り、オブジェクトがオブジェクトを格納するために実際に内部で使用するものをすべて維持する責任があります。内部で使用されるコレクションのタイプに基づいて動作をカスタマイズできます。

リストを考えてみましょう。配列を内部的に使用してデータを格納し、必要に応じて新しいオブジェクトを格納するために配列のサイズ変更を処理します。リストについてそれを知る必要はありません。概念的には、要素の挿入と削除を可能にする、順序付けられたインデックス付きのコレクションです。リンクリスト、赤黒木などを使用して実装できた可能性があります。それらは、パフォーマンスと複雑さに影響を及ぼします。

適切なケースに戻ります。追加のプロパティを持つリストであることが意図されているオブジェクトは、その内部データ構造を非表示にする必要があります。ユーザーは、そこに要素を保持しているリストがあることを知る必要はありません。つまり、オブジェクトは、それ自体の内部データ構造をインスタンス化する方法を知っている必要があり、呼び出し元が内部リストに作用する新しい要素を挿入するために使用するメソッドを公開する必要があります。

唯一の例外は、他のクラスのサブセットのいずれかに適用できる新しい機能を追加する「ラッパー」の例外であり、特定の使用法で新しいクラスを「ラップ」するクラスをユーザーが指定できるようにすることが重要です。例はBlockingCollectionです。これにより、コレクションに対して同時操作を実行しているスレッドを、その操作を実行することが有効で安全になるまでブロックする機能が追加されます(たとえば、コレクションが空の場合、BlockingCollectionからアイテムを取得しようとするスレッドはブロックされます。別のスレッドが何かを追加するまで)。作成時に、BlockingCollectionがIProducerConsumerCollectionインターフェイスの特定の実装を使用するように指定できます。ほとんどの場合、同じ名前空間に組み込まれている「同時」コレクションの1つになります。ConcurrentBag、ConcurrentQueue、ConcurrentDictionaryなど。この場合でも、「デフォルト」オプションがあります。使用する内部Concurrent構造を指定せずにBlockingCollectionオブジェクトをインスタンス化でき、オブジェクトはデフォルトでConcurrentQueueになります。

于 2012-04-20T18:22:31.867 に答える
2

リストがクラスのインスタンスのフィールド/メンバーであると仮定するとnew、クラスのコンストラクターでリストを作成することをお勧めします。

public class SpecialObject
{
    List<something> myList;
    public SpecialObject()
    {
        myList = new List<something>();
    }
}

または、コンストラクターなしで同じことを実行します。

public class SpecialObject
{
    List<something> myList = new List<something>();
}
于 2012-04-20T18:13:58.683 に答える