私が設計しているクラス内で何が起こっているかを正確に伝える命名規則を考えようとしています。二次的な注意として、私は 2 つのほぼ同等のユーザー API のどちらかを決定しようとしています。
状況は次のとおりです。
中心的なデータ構造の 1 つに、1) 蓄積、2) 分析、3) クエリ実行の 3 つのフェーズがある科学アプリケーションを構築しています。
私の場合、これは空間モデリング構造であり、内部で KDTree を使用して 3 次元空間内のポイントのコレクションを分割します。各ポイントは、周囲環境の 1 つまたは複数の属性を表し、測定自体について一定レベルの信頼性があります。
コレクションに (場合によっては多数の) 測定値を追加した後、オブジェクトの所有者は、該当するフィールド内のどこかにある新しいデータ ポイントで内挿された測定値を取得するためにクエリを実行します。
API は次のようになります (コードは Java ですが、それほど重要ではありません。わかりやすくするために、コードは 3 つのセクションに分かれています)。
// SECTION 1:
// Create the aggregation object, and get the zillion objects to insert...
ContinuousScalarField field = new ContinuousScalarField();
Collection<Measurement> measurements = getMeasurementsFromSomewhere();
// SECTION 2:
// Add all of the zillion objects to the aggregation object...
// Each measurement contains its xyz location, the quantity being measured,
// and a numeric value for the measurement. For example, something like
// "68 degrees F, plus or minus 0.5, at point 1.23, 2.34, 3.45"
foreach (Measurement m : measurements) {
field.add(m);
}
// SECTION 3:
// Now the user wants to ask the model questions about the interpolated
// state of the model. For example, "what's the interpolated temperature
// at point (3, 4, 5)
Point3d p = new Point3d(3, 4, 5);
Measurement result = field.interpolateAt(p);
私の特定の問題ドメインでは、SECTION 2 で少量の増分作業 (ポイントをバランスの取れた KDTree に分割する) を実行できます。
また、SECTION 3 で発生する可能性のある少量の作業 (いくつかの線形補間の実行) があります。
しかし、セクション 2 と 3の間で実行しなければならない膨大な量の作業 (テイラー級数とエルミート関数を使用して、カーネル密度推定器を構築し、高速ガウス変換を実行しますが、それはまったく的外れです) があります。
過去に、データ構造を構築するために遅延評価を使用したことがありました (この場合は、「interpolateAt」メソッドの最初の呼び出し時です)。しかし、ユーザーが「field.add」を呼び出すと、 ()" メソッドをもう一度使用すると、それらのデータ構造を完全に破棄して、最初からやり直す必要があります。
他のプロジェクトでは、ユーザーが明示的に「object.flip()」メソッドを呼び出して、「追加モード」から「クエリ モード」に切り替える必要がありました。このような設計の良いところは、ハードコア計算が開始される正確な瞬間をユーザーがより適切に制御できることです。しかし、API コンシューマがオブジェクトの現在のモードを追跡するのは面倒です。さらに、標準的な使用例では、クエリの発行を開始した後、呼び出し元がコレクションに別の値を追加することはありません。ほとんどの場合、データ集計はクエリの準備よりも完全に優先されます。
このようなデータ構造の設計をどのように処理しましたか?
新しいデータがコレクションに入ったときに中間データ構造を捨てて、オブジェクトにその重い分析を怠惰に実行させたいですか? それとも、データ構造を追加モードから照会モードに明示的に切り替えるようにプログラマーに要求しますか?
そして、このようなオブジェクトの命名規則を知っていますか? 私が考えていないパターンはありますか?
編集時:
この例で使用した「ContinuousScalarField」という名前のクラスについては、混乱と好奇心があるようです。
これらのウィキペディアのページを読むと、私が話していることのかなり良いアイデアを得ることができます:
地形図を作成したいとしましょう (これは私の正確な問題ではありませんが、概念的には非常に似ています)。したがって、1 平方マイルの領域で 1,000 の高度測定を行いますが、測量機器には標高でプラスまたはマイナス 10 メートルの誤差があります。
すべてのデータ ポイントを収集したら、値を補間するだけでなく、各測定のエラーも考慮に入れるモデルにそれらをフィードします。
トポ マップを描画するには、ピクセルを描画する各ポイントの標高をモデルにクエリします。
単一のクラスがクエリの追加と処理の両方を担当する必要があるかどうかという質問については、100% 確信はありませんが、そうだと思います。
同様の例を次に示します。HashMap クラスと TreeMap クラスを使用すると、オブジェクトの追加とクエリの両方を実行できます。追加とクエリのための個別のインターフェイスはありません。
クエリ メカニズムをサポートするために内部データ構造を継続的に維持する必要があるため、どちらのクラスも私の例に似ています。HashMap クラスは定期的に新しいメモリを割り当て、すべてのオブジェクトを再ハッシュし、オブジェクトを古いメモリから新しいメモリに移動する必要があります。TreeMap は、赤黒木データ構造を使用して、木のバランスを継続的に維持する必要があります。
唯一の違いは、データ セットが閉じていることがわかったら、すべての計算を実行できる場合に、クラスが最適に実行されることです。