それらは、グローバル変数が行うのとほぼ同じ方法で再利用性を低下させます: メソッドの計算が、メソッドの外部にあるがパラメータとして渡されない状態 (たとえば、クラス フィールド) に依存する場合、メソッドは再利用性が低くなります。それが存在するオブジェクト/クラスの状態に(またはさらに悪いことに、完全に別のクラスに)。
編集:わかりました、これはより明確にするための例です。ThreadLocal
質問のためだけに使用しましたが、一般的にグローバル変数に適用されます。最初の N 個の整数の合計を複数のスレッドで並列に計算したいとします。これを行う最善の方法は、各スレッドのローカル合計を計算し、最後にそれらを合計することです。何らかの理由でcall
、それぞれのメソッドが、異なるクラスでグローバル (静的) 変数として定義されている変数をTask
使用することにしました。ThreadLocal sum
class Foo {
public static ThreadLocal<Long> localSum = new ThreadLocal<Long>() {
public Long initialValue() {
return new Long(0);
}
};
}
class Task implements Callable<Long> {
private int start = 0;
private int end = 0;
public Task(int start, int end) {
this.start = start;
this.end = end;
}
public Long call() {
for(int i = start; i < end; i++) {
Foo.localSum.set(Foo.localSum.get() + i);
}
return Foo.localSum.get();
}
}
コードは正しく機能し、グローバル合計の期待値を返しますが、クラスTask
とそのcall
メソッドがクラスに厳密に結合されていることに気付きFoo
ます。Task
クラスを別のプロジェクトで再利用したい場合は、Foo
クラスも移動する必要があります。そうしないと、コードがコンパイルされません。
これは意図的に複雑な単純な例ですが、「隠された」グローバル変数の危険性を見ることができます。また、コードを読んでいる他の誰かがクラスFoo
を検索し、定義が何であるかを確認する必要があるため、可読性にも影響しFoo.localSum
ます。クラスはできるだけ自己完結型に保つ必要があります。