91

Mapを返すメソッドを書いているとしましょう。例えば:

public Map<String, Integer> foo() {
  return new HashMap<String, Integer>();
}

しばらく考えた結果、このマップが作成されたら変更する必要はないと判断しました。したがって、 ImmutableMapを返したいと思います。

public Map<String, Integer> foo() {
  return ImmutableMap.of();
}

戻り値の型を汎用の Map のままにする必要がありますか、それとも ImmutableMap を返すように指定する必要がありますか?

ある面では、これがまさにインターフェイスが作成された理由です。実装の詳細を非表示にします。
一方で、このままにしておくと、他の開発者はこのオブジェクトが不変であるという事実を見逃す可能性があります。したがって、不変オブジェクトという主要な目標を達成することはできません。変更できるオブジェクトの数を最小限に抑えることで、コードをより明確にします。最悪の場合、しばらくすると誰かがこのオブジェクトを変更しようとする可能性があり、実行時エラーが発生します (コンパイラは警告しません)。

4

9 に答える 9

70
  • 公開 API を作成していて、その不変性が設計の重要な側面である場合、メソッドの名前で返されるマップが不変であることを明確に示すか、または具体的な型の地図。私の意見では、javadoc で言及するだけでは十分ではありません。

    どうやら Guava 実装を使用しているようなので、ドキュメントを調べましたが、これは抽象クラスであるため、実際の具象型に少し柔軟性があります。

  • 内部ツール/ライブラリを作成している場合は、単純な を返すだけの方がはるかに受け入れられMapます。人々は、呼び出しているコードの内部について知っているか、少なくとも簡単にアクセスできるようになります。

私の結論は、明示的であることは良いことであり、物事を偶然に任せてはならないということです。

于 2016-06-28T23:49:58.540 に答える
14

一方で、このままにしておくと、他の開発者はこのオブジェクトが不変であるという事実を見逃す可能性があります。

javadocs でそれについて言及する必要があります。開発者はそれらを読んでいます。

したがって、不変オブジェクトという主要な目標を達成することはできません。変更できるオブジェクトの数を最小限に抑えることで、コードをより明確にします。最悪の場合、しばらくすると誰かがこのオブジェクトを変更しようとする可能性があり、実行時エラーが発生します (コンパイラは警告しません)。

コードをテストせずに公開する開発者はいません。そして、それをテストすると、例外がスローされ、理由だけでなく、不変マップに書き込もうとしたファイルと行も表示されます。

Mapただし、含まれているオブジェクトではなく、それ自体のみが不変になることに注意してください。

于 2016-06-28T23:37:40.163 に答える
5

それはクラス自体に依存します。GuavaImmutableMapは、可変クラスへの不変ビューになることを意図していません。クラスが不変で、基本的に である構造を持っている場合はImmutableMap、戻り型を にしImmutableMapます。ただし、クラスが変更可能な場合は変更しないでください。あなたがこれを持っている場合:

public ImmutableMap<String, Integer> foo() {
    return ImmutableMap.copyOf(internalMap);
}

Guava は毎回マップをコピーします。それは遅いです。しかし、internalMapすでに だった場合はImmutableMap、まったく問題ありません。

クラスを return に制限しない場合は、代わりに次のようImmutableMapに返すことができます。Collections.unmodifiableMap

public Map<String, Integer> foo() {
    return Collections.unmodifiableMap(internalMap);
}

これは、マップに対する不変のビューであることに注意してください。internalMap変更すると、 のキャッシュ コピーも変更されますCollections.unmodifiableMap(internalMap)。ただし、私はまだゲッターの方が好きです。

于 2016-06-29T15:00:58.397 に答える
-1

これはおそらく意見の問題ですが、ここでのより良いアイデアは、マップ クラスのインターフェイスを使用することです。このインターフェイスは、不変であることを明示的に示す必要はありませんが、親クラスのセッター メソッドをインターフェイスで公開しなければ、メッセージは同じになります。

次の記事をご覧ください。

アンディ・ギブソン

于 2016-06-29T01:10:58.380 に答える