1

私は自由時間に単純なデータ ストレージ プロジェクトでファクトリ パターンを使用して、ファクトリ パターンに頭を悩ませることに取り組んでいます。アイデアは、単純なデータを取得し、VB.NET の単純なファクトリ パターンを使用してデータベースに保存することです。パターン自体の基本的な理解はできていると思いますが、苦労しているのは、ファクトリ クラスをアーキテクチャにきれいに適合させる方法です。このプロジェクトには、基本的に次のような標準の 3 層アーキテクチャがあります。

プレゼンテーション

 -Presentation.Common
 -Presentation.DataStorageWebAppName

仕事

 -BusinessLayer.Common
 -BusinessLayer.DataStorageAppName

データ

 -DataLayer.Common
 -DataLayer.DataStorageAppName

一般

 -Common
 -Common.DataStorageAppName

インターフェース

 -Interfaces.Common
 -Interfaces.DataStorageAppName

アプリケーションの設計に問題がある特定のシナリオを強調するために、例を挙げましょう。ビジネス層で、BusinessLayer.DataStorageAppName DLL に Foo というクラスを作成するとします。これには、Interfaces.DataStorageAppName DLL に存在するインターフェイス IFoo があります。単純なファクトリ パターンを使用してインターフェイス IFoo を介してクラス Foo のインスタンスを作成するには、現在、BusinessLayer.DataStorageAppName に Factory クラスを作成し、共有/静的メソッドを記述して、IFoo インターフェイスを介してインスタンスを作成します。後で、私が理解しているように、(理論上) 他に多くのことをする必要なく、この Factory クラスが返すオブジェクトを交換することができました。

要点を言えば、これは機能しますが、循環参照を回避できるように、いくつかの Factory クラスを作成することを余儀なくされています。基本的に DLL ごとに 1 つです。キャッスルウィンザーなどのサードパーティのソリューションを使用せずに、これらのファクトリクラスを実装するよりクリーンな方法はありますか?ここでは基本的な概念が欠けているようです。オブジェクトインスタンスの配布を担当するアーキテクチャで、単一の「リポジトリ」を持つことが可能であるように思われます。

前もって感謝します!

4

3 に答える 3

1

IFoo の実装とそれを返すファクトリ メソッドが、BusinessLayer とは別のアセンブリに存在できない (したがって、すべてのクライアント アセンブリからこの新しいアセンブリを参照できる) 理由はありますか? 理由がある場合、IFoo も BusinessLayer で定義する必要がある (したがって、Interfaces アセンブリへの参照を必要としない) 可能性はありますか?

インターフェイスがビジネス レイヤー以外からもアクセスできる必要があり、実装が実際にビジネス レイヤーに依存している場合は、ファクトリ メソッドだけでなく、もう少し何かを調べる必要があります。制御の反転/依存性注入の原則のいくつかを使用して、懸念をより適切に分離できます。

[OP からのその後の回答に応じて編集] Factory Method は、IMO では、IoC アプローチと見なすには十分ではありません。最適なのは、特定の実装の構築をカプセル化して、複数の場所で再利用するか、単に敷物の下で一掃することです。私に欠けているのは、依存関係の破壊です。ファクトリ メソッドは、呼び出されたのと同じアセンブリに存在するため、返される具象型を変更するには、再コンパイルする必要があります。次の 2 つの違いを考えてみましょう。

public class FooConsumer1
{
    public void DoStuff()
    {
        IFoo myFoo = new Foo();
        myFoo.Bar();
    }
}

と:

public class FooConsumer2
{
    public void DoStuff()
    {
        IFoo myFoo = FooFactory.getFoo();
        myFoo.Bar();
    }
}

public class FooFactory
{
    public static IFoo GetFoo()
    {
        return new Foo();
    }
}

2 番目の利点は、複数の場所で IFoo を作成する場合、Foo を置き換える SuperFoo クラスを作成するときに変更する場所が 1 つしかないことです。また、何らかの方法で動的に 2 つの実装を決定する場合、ロジックを配置する場所は 1 つだけです。もう1つの利点は、コンストラクターが複雑/醜い場合、または構成設定などを検索するために追加のコードが必要な場合、それを使用しているメソッドからすべてを隠すことです。

ただし、これらのどれも (少なくとも私の考えでは) 実際には、このメソッドとそれが使用する具体的な実装との間の依存関係を解消するのに役立ちません。

于 2008-12-30T11:25:48.980 に答える
1

私はよりシンプルなアプローチを取りました。Entity クラスを定義し、エンティティのリスト (List< Entity >) を生成するファクトリを用意しました。取得したい型をファクトリに伝えます。型がテーブルであると想定し、プロパティが列であると想定し、SQL を生成し、データを取得し、その型の新しいインスタンスのリストを作成します。

ファクトリは Entity オブジェクトを受け取り、リフレクションを使用してデータベース内の値を更新することもできます。

ここで行う必要があるのは、特定のデータベースのエンティティ クラスのセットを作成することだけです。これはデータ転送オブジェクトでもあります。

于 2008-12-29T21:32:28.507 に答える
0

複数のファクトリ クラスが異なる問題を処理する場合は、ファンキーである必要はありません。静的ファクトリ メソッドを使用するのではなく、使用するファクトリのインスタンスを作成することをお勧めします。その後、ファクトリ自体がインターフェイスを実装できるようになり、おそらくいくつかのファンキーさがなくなります。

于 2008-12-31T00:34:04.973 に答える