2

Spring フレームワークで DI を使用するようにレガシー コードを変更しようとしています。私は、それを実装する最も適切な方法はどれなのか疑問に思っている具体的なケースがあります。

Java デスクトップ アプリケーションです。データストアからのデータのクエリ/変更に使用される DataManager インターフェイスがあります。現在、格納用の XML ファイルを使用する実装は 1 つだけですが、将来的には SQL 実装を追加することが可能です。また、単体テストのために、モックが必要になる場合があります。

現在、データ マネージャーを必要とするすべてのコードは、ファクトリを使用して取得されます。ファクトリのソース コードは次のとおりです。

public class DataManagerFactory   
{  
    private static DataManagerIfc dataManager;

    public static DataManagerIfc getInstance()
    {
        // Let assume synchronization is not needed
        if(dataManager == null)
            dataManager = new XMLFileDataManager();

        return dataManager;
    }
}

DI と Spring を使用するようにアプリケーションを変更する方法が 3 つあります。

I. 依存関係をファクトリにのみ挿入し、他のコードを変更しないでください。

新しいコードは次のとおりです。

public class DataManagerFactory  
{
    private DataManagerIfc dataManager;

    public DataManagerFactory(DataManagerIfc dataManager)
    {
        this.dataManager = dataManager;
    }

    public DataManagerIfc getDataManager()
    {
        return dataManager;
    }

    public static DataManagerIfc getInstance()
    {
        return getFactoryInstance().getDataManager();
    }

    public static DataManagerFactory getFactoryInstance()
    {
        ApplicationContext context =
                    new ClassPathXmlApplicationContext(new String[] {"com/mypackage/SpringConfig.xml"});

        return context.getBean(DataManagerFactory.class);
    }
}

そして、Bean の説明を含む XML:

<bean id="dataManagerFactory"
            class="com.mypackage.DataManagerFactory">
    <constructor-arg ref="xmlFileDataManager"/>
</bean>

<bean id="xmlFileDataManager"
    class="com.mypackage.datamanagers.xmlfiledatamanager.XMLFileDataManager">
</bean>

Ⅱ.データマネージャーを使用しているすべてのクラスを変更して、コンストラクターを介してクラス変数として格納するようにします。一連の作成が開始される「ルート」クラスに対してのみ、Spring Bean 定義を作成します。

III. Ⅱと同じ。ただし、データ マネージャーを使用しているすべてのクラスに対して、Spring Bean 定義を作成し、Spring Ioc コンテナーを使用してそのようなすべてのクラスをインスタンス化します。

私は DI の概念に慣れていないので、正しい「ベスト プラクティス」ソリューションとなるすべてのアドバイスに感謝します。よろしくお願いします。

4

3 に答える 3

2

オプション 3 を使用します。

最初のオプションは、コードをテストできないままにします。モック DataManager を返すように、静的ファクトリ メソッドを簡単にモックすることはできません。

2 番目のオプションでは、コードをテスト可能にするために、ルート クラスにすべての非ルート クラスのすべての依存関係を認識させる必要があります。

3 番目のオプションは、依存性注入を実際に使用します。この場合、各 Bean は直接的な依存性についてのみ認識し、DI コンテナーによって注入されます。

于 2013-02-04T13:31:18.887 に答える
0

ええと... そもそもなぜ工場を書いたのですか?Spring は、コードの記述方法を変更することを意図していません (Spring に合わせるためだけではありません)。そのため、よく知られているパターンを使用するため、ファクトリを維持することは正しいことです。依存関係をファクトリに注入すると、その動作が保持されます。

于 2013-02-04T13:30:36.097 に答える