パブリックメソッドからハッシュテーブルを返す際の何が問題になっていますか?


9

クラスを作成してそのオブジェクトを返すのではなく、複数のアイテムを返したいときに、パブリックメソッドからハッシュテーブルを返す際の設計上の問題は何ですか?

問題がある場合は、どのような状況でそれを行うのが理にかなっていますか?

言語が動的かどうかによって、この質問に対する答えはどのように変わりますか?

編集:これは、キーが定数であり、データではなくコードの一部であることを明確にするためです。通常、クラスを作成するためのもの。問題は、クラスの作成が実際に正しい選択であるように思われる場合に、代わりにハッシュテーブルを使用することが間違っている理由です。

回答:


11

名前と値のペアとして任意の数の値を保持するハッシュテーブルよりも適切に定義されたクラスを戻り値の型として使用します。

  1. 最初かつ最も重要なポイントは-保守性です。コードを見ると、新しいプログラマーは、メソッドが返す値が何であるかを言うことはできません。新しい人がコードを見てこれを理解できない場合、誰かがそのデータにキー/値を追加したり、アプリケーションを拡張しようとすると、コードは役に立たず、エラーが発生しやすくなります。

  2. メソッドは、呼び出し元とサービスの間のコントラクトです。メソッドで最も重要なことは、その入力と出力です。この入力と出力は、読みやすく、理解しやすく、自己文書化する必要があります。Personクラスを姓、名、年齢を持つ戻り値として使用する場合-自己文書化されています。こののJavadocを生成すると、ユーザーはクラス間を移動してこれをよりよく理解できます。ハッシュテーブルを使用する場合は、誰も読まないコメントで説明するか、状況が変化したときに更新する必要があります。

  3. HashMap<String,String>returnステートメントに数字(たとえば年齢)を追加する場合のように、ジェネリックを使用することはできません。ジェネリックスを使用しない場合は、オブジェクト間で実際の型にキャストする必要があります。動的タイピングを使用する場合、これを保存できます。

  4. また、コンパイル時に問題を検出するよりも、実行時エラーが発生する可能性が高くなります。たとえば、誰かがハッシュマップからエントリを削除し、古い呼び出し元の1つがそのエントリを予期している場合、クライアントは実行時に失敗します。コンパイル時にこの問題をキャッチすることを常にお勧めします。

  5. 戻り値の型としてハッシュマップを使用したい場合など、不変の型を返すのは難しいでしょう。ただし、独自に定義したユーザーを使用する場合は、これを制御できます。

最初にいくつかのクラスを作成することを回避できるため、戻り値の型としてハッシュマップを使用するのは魅力的ですが、将来的にコードを維持するのは悪夢になります。オブジェクト指向に行く!!!!


1
あなたは質問を正しく理解したようです。ありがとう。
ムハンマドハサンカーン

8

問題の1つは、多くの場合、ハッシュテーブルのキーが文字列になることです。したがって、メソッドの利用者は、データを抽出するためにどのキーを使用するかを事前に知っておく必要があります。これにより、データにアクセスするときにスペルミスによるエラーが発生する可能性があります。

別の欠点はリファクタリングです。後でメンバーの名前を変更することにした場合は、変更する必要のある一連の魔法の文字列があります。最も優れたIDEが提供するリファクタリングツールを使用してクラスメンバーの名前を変更する方がはるかに簡単です。ハッシュテーブルを使用すると、すべてのソースファイルに対して検索/置換操作を実行する必要があり、問題が発生する可能性があります。

最後に、名前とタイプの両方に関して、メンバーアクセスのコンパイル時のチェックが失われます。ハッシュテーブルに含まれるオブジェクトのタイプが1つだけの場合、後者はそれほど問題になりませんが、同じ階層チェーン内でも多くのタイプが含まれている場合は、実際に言語のタイプシステムを利用してコンパイル時間をチェックする必要があります。ほとんどのIDEには、ある種のインテリセンス/オートコンプリート機能があります。これらは型システムを調べることで機能しますが、ハッシュテーブルキーを使用することはできません。

時間のようです値の両方際にハッシュテーブル(またはキーと値のペアのような他のコレクション)を返すために適切で、あなたはこれを使用すると、キーはコンパイル時に知られていません。たとえば、クエリ文字列を解析してキーと対応する値を返すメソッドがある場合は、ハッシュテーブルが適しています。この場合、ある種の不変または読み取り専用のハッシュテーブルを返すことも検討してください。

編集 -この回答で指摘されたポイントのほとんどは、動的言語について話しているときに適用されなくなります:)


言語が動的な場合はどうなりますか?
ムハンマドハサンカーン

私は動的言語の専門家ではないので、他の誰かがおそらくより良い答えを提供できるでしょう。しかし、動的言語がコンパイル時の型チェックを実行しないことは知っています。しかし、その場合、オブジェクトを返すと、ハッシュテーブルを返すにはそれほど異ならない..です
MattDavey

3
@Hasan Khan:その場合、実際にはハッシュテーブルとクラスインスタンスの間に違いはないかもしれません。たとえば、Javascriptではすべてのオブジェクトハッシュテーブルであり、object.propertyはobject ['property']とまったく同じです
Michael Borgwardt

「ハッシュテーブルを使用すると、すべてのソースファイルに対して検索/置換操作を実行する必要が生じ、問題が発生する可能性があります。」貧弱なキーを選択し、標準のキーを1か所で定義するために標準のキーを除外しようとしたことがない場合のみ
Donal Fellows

7

これに対する最も重要な議論は、消費者に情報を公開しすぎていることです。使用するコードは、それが何らかのキーと値のコレクション(辞書)であることを知るだけで十分です。それがハッシュマップ、連想リスト、トライなどとして実装されているかどうかは、比較的興味深いものではありません。したがって、適切な方法はIDictionary、実際のタイプではなく、適切なインターフェース(、または選択した言語が使用するもの)で返すことです。

これはすべて、実際にデータを表す辞書が必要であることを前提としています。つまり、データはキーと値のペアで構成され、キーはデータセット間で一意であり、コンパイル時に修正できません。既知のキーがある場合は、データに適切なタイプ(または必要に応じて複数)を作成する必要があります。キー自体をデータの一部と見なすか、コードの一部と見なすかによります。

編集

明確にするために、ここでは辞書という用語を使用して、最も一般的なタイプのKey-Valueデータ構造を意味しています。Python dictや.NET などの言語固有の実装を意味するものではありませんDictionary


1
+1「キー自体をデータの一部と見なすか、コードの一部と見なすかによります。」-それはそれを置くのに良い方法です。たとえば、「辞書」という用語が「地図」とは対照的にどれほど普遍的であるかはわかりません。
MattDavey 2012年

辞書を返すことは意図されていませんでした。キーはデータではなくコードの一部でした。
ムハンマドハサンカーン

本当の問題は、「適切なタイプを作成する必要がある」の背後にある理由です。質問はなぜですか?
ムハンマドハサンカーン

2

私が自分に尋ねる質問の1つは、「この辞書でキーが変更されているか」ということです。それらが定数の場合、オブジェクトまたはその他の適切なデータ構造を返す必要があります。それらが動的な場合は、ある種の辞書スタイルの構造を返すことができます。最後に、定数になるキーと不明な動的キーのセットがある場合、固定値とオーバーフロー用の辞書の種類を含むハイブリッドデータ構造を返すことができます。


確かにあなたのアドバイスは正しいですが、問題は、クラスがより良い選択であるときにハッシュテーブルを使用することを選択することの何が問題になっているのですか?
ムハンマドハサンカーン

/でもない; クラスには、必要に応じて辞書を簡単に含めることができます。
ワイアットバーネット2012年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.