コードの繰り返しが多いことは一般的に悪いことであり、これを最小限に抑えるのに役立つ設計パターンがあります。ただし、言語自体の制約により、避けられない場合もあります。から次の例を取り上げますjava.util.Arrays
。
/**
* Assigns the specified long value to each element of the specified
* range of the specified array of longs. The range to be filled
* extends from index <tt>fromIndex</tt>, inclusive, to index
* <tt>toIndex</tt>, exclusive. (If <tt>fromIndex==toIndex</tt>, the
* range to be filled is empty.)
*
* @param a the array to be filled
* @param fromIndex the index of the first element (inclusive) to be
* filled with the specified value
* @param toIndex the index of the last element (exclusive) to be
* filled with the specified value
* @param val the value to be stored in all elements of the array
* @throws IllegalArgumentException if <tt>fromIndex > toIndex</tt>
* @throws ArrayIndexOutOfBoundsException if <tt>fromIndex < 0</tt> or
* <tt>toIndex > a.length</tt>
*/
public static void fill(long[] a, int fromIndex, int toIndex, long val) {
rangeCheck(a.length, fromIndex, toIndex);
for (int i=fromIndex; i<toIndex; i++)
a[i] = val;
}
上記のスニペットは、ソース コードに 8 回表示されます。ドキュメンテーション/メソッド シグネチャのバリエーションはほとんどありませんが、メソッド本体はまったく同じでint[]
、short[]
ルート配列型、、、、、、、、およびchar[]
byte[]
boolean[]
double[]
float[]
Object[]
反省(それ自体はまったく別の主題です)に頼らない限り、この繰り返しは避けられないと私は信じています。ユーティリティ クラスとして、このように反復的な Java コードが非常に集中することは非常に非典型的であることは理解していますが、ベスト プラクティスを使用しても反復は発生します。リファクタリングは、常に可能であるとは限らないため、常に機能するとは限りません (明らかなケースは、繰り返しがドキュメントにある場合です)。
明らかに、このソース コードを維持することは悪夢です。ドキュメンテーションのわずかなタイプミス、または実装のマイナーなバグは、何回繰り返しても乗算されます。実際、最良の例はたまたまこの正確なクラスを含んでいます:
Google Research ブログ - おまけ、おまけ - すべてを読む: ほぼすべてのバイナリ検索とマージソートが壊れている (Joshua Bloch、ソフトウェア エンジニア)
このバグは驚くほど微妙なもので、単純で単純なアルゴリズムと多くの人が考えていたもので発生しています。
// int mid =(low + high) / 2; // the bug
int mid = (low + high) >>> 1; // the fix
上記の行は、ソース コードで 11 回表示されます。
だから私の質問は:
- この種の反復的な Java コード/ドキュメントは、実際にはどのように処理されますか? それらはどのように開発、維持、およびテストされますか?
- 「オリジナル」から始めて、できるだけ成熟させてから、必要に応じてコピーして貼り付け、間違いがなかったことを願っていますか?
- 元のファイルで間違いを犯した場合は、コピーを削除して複製プロセス全体を繰り返すことに慣れていない限り、どこでも修正できますか?
- そして、これと同じプロセスをテスト コードにも適用しますか?
- Java は、この種の目的のために、使用が制限されたソース コードの前処理を行うことで利益を得るでしょうか?
- おそらく Sun は、この種の反復的なライブラリ コードの作成、保守、文書化、およびテストを支援する独自のプリプロセッサを持っているのでしょうか?
コメントで別の例が要求されたので、Google Collections からこれを取得しました: com.google.common.base.Predicates行 276-310 ( AndPredicate
) vs 行 312-346 ( OrPredicate
)。
これら 2 つのクラスのソースは、次の点を除いて同一です。
AndPredicate
vsOrPredicate
(それぞれがそのクラスに 5 回出現)"And("
vsOr("
(それぞれのtoString()
方法で)#and
vs#or
(@see
Javadoc コメント内)true
vsfalse
(inapply
;!
は式の外に書き直すことができます)-1 /* all bits on */
対0 /* all bits off */
中hashCode()
&=
対|=
中hashCode()