8

抽象クラス Drink と、実行時に作成する Drink の種類 (Wine、Beer など) を選択するファクトリ メソッドがあるとします。

各 Drink は、それ自体を適切に初期化するためにいくつかの引数が必要です。これらのいくつかはすべてのドリンクに共通です。たとえば、それらはすべて DrinkConfig 引数を必要とする場合があります。

ただし、各ドリンクにも独自の要件がある場合があります。おそらく、Wine は自分自身を初期化するために Sommelier ヘルパー オブジェクトを必要とします。Beer はそれを必要としませんが、独自のヘルパー オブジェクトが必要な場合があります。

では、ファクトリ メソッドには何を渡す必要がありますか? これを呼び出すと、すべてのヘルパー オブジェクトが利用可能になるので、それらすべてをファクトリに渡すことができます。しかし、これは多くの議論になる可能性があります。これを設計するより良い方法はありますか?

編集:ファクトリでヘルパー オブジェクトを作成することはできないと仮定しましょう。それらは発信者からのみ利用できます。

4

7 に答える 7

4

ファクトリ クラスにさまざまなオーバーロード メソッドを作成します。

public class DrinkFactory {

    public static Drink CreateBeer(DrinkConfig config, string hops) {
        return new Beer(config, hops);
    }

    public static Drink CreateWine(DrinkConfig config, string grapes, int temperature) {
        return new Wine(config, grapes, temperature);
    }
}

編集:

Factory クラスにメソッドを 1 つだけ持つことが望ましい場合は、代替の実装は次のようになります。

public enum DrinksEnum {
    Beer,
    Wine
}

public class DrinkFactory {

    public static Drink CreateDrink(DrinksEnum drinkType, DrinkConfig config) {
        switch(drinkType) {
            case DrinksEnum.Beer:
                return new Beer(config);
            case DrinksEnum.Wine:
                return new Wine(config);
            default:
                throw new ApplicationException("Drink type not recognised.");
        }
    }
}
于 2009-05-13T01:01:02.977 に答える
2

ファクトリ メソッドは、値を作成する方法の詳細を抽象化する必要があります。したがって、ヘルパー オブジェクトをファクトリ メソッドに渡す必要はありません。ファクトリ メソッドは、必要なヘルパー オブジェクトを作成し、それを適切なコンストラクターに渡す必要があります。

于 2009-05-13T01:04:57.617 に答える
1

Factory は、最初に非常によく似たオブジェクトを作成する必要があります。つまり、これらのオブジェクトはすべて飲み物ですが、それぞれの飲み物は単純に大きく異なるため、ファクトリ メソッドは適切ではない可能性があります。

そうは言っても、代わりに、設定するプロパティの数と同じサイズのオブジェクトのリストを渡すことができます。各オブジェクトは、適切なオブジェクトのコンストラクターに設定する値を、これらの変数を設定する順序で表します。これの欠点は、呼び出しを行う前にファクトリの外部でリストをフォーマットする必要があることです。これはやや不器用です。

于 2009-05-13T01:12:05.163 に答える
0

Builderこれは、パターンの完璧なケースのように見えます。Factory類似したオブジェクトを作成する場合はパターンを使用し、Builder複雑で異なるオブジェクトを作成する場合はパターンを使用します。Factoryこの問題にパターンを使用しようとすると、さまざまなオブジェクトに対して、多くの異なる初期化コンストラクター (パラメーターの数/型が異なる) が発生します。

于 2014-05-04T19:00:56.927 に答える
0

このような場合、私は通常、変数を渡すのではなく、他のソリューションに目を向けます。

たとえば、あなたの場合-ソムリエを必要とするWineFactoryは、適切なワインを構築できます-

これは、ランタイム依存性注入の優れた使用例です。何らかの形の依存性注入フレームワークを使用すると、これらのプロパティをすべて渡さなくても、これを非常に単純で理解しやすく、簡単に機能させることができます。

于 2009-05-13T01:08:57.107 に答える
0

成分が基本クラス「DrinkIngredients」から派生した単純なソリューションを提供したいと思います。特定の飲み物に使用するサブクラスを一致させる必要があります。

どうやら、材料のために別の工場を作りたくなるかもしれませんが、それは鶏と卵の問題につながります.

于 2009-05-13T01:03:17.667 に答える
0

一般に、これらの詳細を非表示にするファクトリ メソッドが存在します。重要な質問の 1 つは、ソムリエがどこから来たのかということです。これらの他のヘルパーがすべてシングルトンであるか、既知のソースから取得できる場合は、ファクトリをインスタンス化して、必要な情報を探してそれらを見つけ、呼び出しコードが必要ないようにします。それを心配する。

また、多くの場合、Spring などのフレームワークを使用して、コードではなく構成ファイルでこれらの関係を記述できるようにします。

実行時に呼び出しコードからヘルパーを渡す必要がある場合は、「引数と結果」という論文を読むことをお勧めします ( http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.50.7565 ) は、複雑な引数をマーシャリングするための一般的なパターンを記述しています。基本的に、必要なパラメータの中間コレクションを作成し、それをファクトリに渡します。

于 2009-05-13T01:03:40.707 に答える