1

私は、文字列ベースの「サービス ロケータ」の概念にまつわる混乱に苦しんでいます。

まず第一に、IoC は優れており、インターフェイスへのプログラミングが最適です。しかし、ここで使用されているイエローページ パターンのどこに大きな利点があるのか​​、コンパイル不要の再構成可能性を除けば、私にはわかりません。

アプリケーション コードは、(Spring) コンテナーを使用してオブジェクトを取得します。コードは必要なインターフェイス (キャスト先)、Spring コンテナー インターフェイス、および必要なオブジェクトの名前のみを知る必要があるため、多くの結合が削除されます。

public void foo(){
   ((MyInterface) locator.get("the/object/I/need")).callMe();
}

もちろん、ロケーターには、あらゆる種類のObject派生物の無数のオブジェクトを取り込むことができます。

しかし、オブジェクトを名前で取得する「柔軟性」が、実際にはタイプセーフでなくルックアップセーフでない方法で依存関係を隠しているという事実に少し当惑しています。そしてそれは型であり、今ではそのすべてが実行時段階に延期されています。

私が考えることができる最も単純で機能的に問題のないパターンは、structオブジェクトのようなアプリケーション全体の巨大なパターンです。

public class YellowPages  {
    public MyInterface the_object_i_need;
    public YourInterface the_object_you_need;
    ....
}

// context population (no xml... is that bad?)
YellowPages locator = new YellowPages();
locator.the_object_i_need=new MyImpl("xyx",true),
locator.the_object_you_need=new YourImpl(1,2,3)


public void foo(){
   locator.the_object_i_need.callMe(); // type-safe, lookup-safe
}

要求されたオブジェクトを解決するようにコンパイラに依頼し、そのタイプが問題ないかどうかを確認する方法/パターン/フレームワークはありますか? それも行うDIフレームワークはありますか?

どうもありがとう

4

2 に答える 2

2

Spring is the only DI framework that I've used, so I can't speak for others, but even though Spring give you the ability to request an object by its name in your code, you don't have to get your Spring beans by name -- in fact, if you do, you're not really capitalizing on the "I" (inversion) in IOC.

The whole principle behind Spring/DI is that your objects shouldn't be asking for a particular object -- it should just have whatever objects it needs handed to it by the IOC container. The distinction is subtle, but it's there. The former approach would resemble the code that you pasted:

public void foo(){
   ((MyInterface) locator.get("the/object/I/need")).callMe();
}

The latter approach, by contrast, doesn't depend on any service locator, nor does it depend on the "name" of the object that it wants:

private ObjectINeed objectINeed;

public void setObjectINeed(ObjectINeed objectINeed) {
    this.objectINeed = objectINeed;
}

public void foo(){
   objectINeed.callMe();
}

It's the IOC container that calls the setObjectINeed() method. DI is definitely tackles the same problem as the service locator pattern, but it goes that extra step towards getting rid of the dependency on your service locator class.

于 2011-09-08T21:54:54.240 に答える
2

あなたが説明しているのは、アンチパターンであり、単純明快です。依存性注入 (可能であればコンストラクターを介して実行) は、制御の反転を行うための推奨される方法です。IOC に関する古い記事では、パターンを実装するための実行可能な方法としてサービスの場所について説明していますが、最近の記事でこれを支持する人を見つけるのは難しいでしょう。

あなたは次の言葉で頭を悩ませています。

しかし、名前でオブジェクトを取得する「柔軟性」が、実際にはタイプセーフでなくルックアップセーフでない方法で依存関係を隠しているという事実に少し戸惑っています。

最新の DI フレームワークのほとんどは、タイプセーフでない部分を回避できますが、依存関係を明示的ではなく暗黙的にすることで、依存関係を隠しています。

このトピックに関する良い記事:

Service Locator はアンチパターンです

于 2011-09-08T21:53:37.707 に答える