2

今日の私の質問は、問題解決の質問ではなく、ベスト プラクティスの理論に関する質問です。Joda-Time に慣れてきました。ユーザー ガイド ( http://joda-time.sourceforge.net/userguide.html#Interface_usage )でこれを読みました。

List や Map などの Collections インターフェースを使用する場合、通常は変数を List または Map の型として保持し、オブジェクトの作成時に具象クラスのみを参照します。

 List list = new ArrayList();
 Map map = new HashMap();

これは非常に奇妙な発言だと思いました。私のプログラミングでは、ある種の API をプログラミングしていない限り、常に変数の具象クラスを保持してきました。変数型の具体的なクラスに対して一般/抽象クラスを保持することが優先される理由を説明するのに役立つ資料はありますか?

説明のために、コンマで区切られた文字列としてオブジェクトのリストが必要なときに使用する簡単なメソッドを作成しました。

public static <T> String CSV(Collection<T> list) {
    boolean first = true;
    StringBuilder sb = new StringBuilder();
    for(Object e : list) {
        if(first)
            first = false;
        else
            sb.append(", ");
        sb.append(e.toString());
    }
    return sb.toString();
}

ここではもちろん、Object[]、LinkedList など、必要なものを何でも渡すことができるように Collection を使用する必要があります。

しかし、別の場所に文字列のセットを格納していて、それを LinkedHashSet にしたい場合、次のように変数を作成します。

LinkedHashSet<String> set = new LinkedHashSet<String>();

また

LinkedHashSet<String> set = new LinkedHashSet<>();

(Java 7 の変更のため)

しかし、Joda-Time のユーザー ガイドによると、次のようにする必要があります。

Set<String> set = new LinkedHashSet<String>();

?

メリットしか思い浮かびません。役に立つ入力/読み物を持っている人はいますか?

ありがとう!

4

5 に答える 5

2

Collection(たとえば)作業する場合、これがどのようにCollection実装されているかは問題ではありません-メソッドを使用したいだけですCollection。この場合、コードは非常に機敏になり、Collection実装を簡単に変更できます。ただし、基本的なインターフェースだけでは不十分な場合は、具体的な参照を使用してください。

これは OOP の基本です。可能であれば、具体的なクラスではなく、抽象化を使用する必要があります。

同様の質問:

于 2013-05-09T15:59:49.287 に答える
0

他の人が使用または変更するコードを書いている場合は、具象型を選択して自分の型を強制的に使用させるよりも、インターフェイスを使用して最適な実装を選択させる方が簡単です。

于 2013-05-09T16:03:54.167 に答える
0

インスタンス化に関する私の一般的な経験則は、ニーズに合った最も基本的なクラスを使用することです。

これが意味することは、この場合、LinkedHashSet を使用していることです。Set のコントラクトによって満たされるメソッドのみを使用することがわかっている場合は、それを Set としてインスタンス化します。これを行う理由は、コードをより将来性のあるものにするためです。たとえば、前に戻って Set がスレッド セーフであることを確認する必要がある場合は、スレッド セーフでない LinkedHashSet ではなく、Concurrent クラスをインスタンス化します。この方法では、下流のコードは変更されず、インスタンス化を更新するだけで済みます。

于 2013-05-09T16:11:44.533 に答える
0

Java には (まだ) 型推論がないため、変数を定義するとき、およびそれに基づいて新しい変数を作成するたびに、変数を明示的に指定する必要があります。型が具象クラスの場合、後でそれを変更したい場合は、それらの宣言もすべて変更する必要があります。リファクタリング ツールを使えば自動化できるかもしれませんが、それでも少し面倒です。抽象型またはインターフェイス型を使用すると、これらの宣言をすべて変更せずに具象型を変更できます。

全体として、どちらも大したことではないと思います。

于 2013-05-09T15:57:01.690 に答える
0

一般に、必要な機能を最も厳密に定義するインターフェースを使用する必要があります。

LinkedList で Queue を使用するいくつかの理由を次に示します。

  • キューは、変数がどのように使用されることを意図しているかを読者に伝えます。これは、はるかに説明的です。
  • オブジェクトの実装を Queue を実装するものに即座に置き換えることができます。
  • DI を使用すると、Queue の実装を知る必要さえなく、後でコードを変更することなく変更できます。
  • Queue メソッドのみを使用する場合は、Queue よりも LinkedList を使用しても何の利点もありません。
  • コンパイラは、キューが不適切に使用されていないと主張できます。

最後の 1 つは、いくつかの理由から非常に大きなポイントです。「キュー」を返すメソッドを作成すると、不適切に処理されないことが期待でき、新しいオブジェクトをどのように操作できるかをユーザーに即座に正確に説明できます。たとえば、リストとして反復されることは意図されていません。

これは独自のインターフェースにも当てはまります。インターフェースを作成して、ある目的のために機能のサブセットを公開し、別の目的のために別のサブセットを公開することもできます...たとえば、同じキューを 2 つの異なる呼び出し元に返すことができます。 「エンキュー」インターフェースを備えたものと「デキュー」インターフェースを備えたもの-「パイプ」がどちらの方向に流れるかが非常に明確になります。

于 2013-05-09T16:05:57.073 に答える