問題は、適切な抽象化を使用しているかどうかだと思います。
最初のケースでは、
interface IHasGetA {
IHasGetB getA();
}
interface IHasGetB {
IHasGetC getB();
}
interface IHasGetC {
ITransmogrifyable getC();
}
interface ITransmogrifyable {
void transmogrify(x,y);
}
mainはタイプIHasGetA
です。問題は、その抽象化が適切かどうかです。答えは簡単ではありません。そして、この場合、それは少し見た目が悪いですが、とにかく理論的な例です。しかし、別の例を作成するには:
main.getA(v).getB(w).getC(x).transmogrify(y, z);
しばしばより良い
main.superTransmogrify(v, w, x, y, z);
後者の例では、両方のためthis
とmain
の種類に依存するv
、w
、x
、y
およびz
。また、すべてのメソッド宣言に6つ以上の引数がある場合、コードの外観はそれほど良くありません。
実際にサービスロケーターには最初のアプローチが必要です。サービスロケーターを介して作成されたインスタンスにアクセスする必要はありません。
そのため、オブジェクトを介して「到達」すると、実際のクラスのプロパティに基づいている場合は、依存関係が多くなります。
ただし、抽象化の作成、つまりオブジェクトを提供することは、まったく別のものです。
たとえば、次のことができます。
class Main implements IHasGetA, IHasGetA, IHasGetA, ITransmogrifyable {
IHasGetB getA() { return this; }
IHasGetC getB() { return this; }
ITransmogrifyable getC() { return this; }
void transmogrify(x,y) {
return x + y;//yeah!
}
}
のmain
インスタンスはどこですかMain
。クラスmain
が依存関係をのIHasGetA
代わりにに減らすと、Main
実際に結合が非常に低くなることがわかります。呼び出し元のコードは、元のオブジェクトの最後のメソッドを実際に呼び出していることすら知らず、実際に分離の程度を示しています。
実装の内部に深く入るのではなく、簡潔で直交する抽象化のパスに沿って到達します。