1

このような抽象ファクトリを実装しました

public abstract class AbstractFactory {

    private static final Map FACTORIES = new HashMap();    

    AbstractFactory(FactoryType type) {
        FACTORIES.put(type, this);
    }   

    public abstract A getA();

    public abstract B getB();

    public static AbstractCatalogFactory getFactory(FactoryType type) {
        return (AbstractCatalogFactory) FACTORIES.get(type);
    }
}

具体的なファクトリは、この抽象ファクトリ コンストラクタを呼び出す必要があります。これにより、各具体的な実装がFACTORIESマップに登録されます。コンストラクターの実行が戻るまで の値を未定義にする必要があるthisように見えるため、コンストラクター内での参照について少し心配しています。this

ありがとう、ドン

4

1 に答える 1

2

thisコンストラクタからのリークについて

コンストラクターの実行が戻るまで の値を未定義にする必要があるthisように見えるため、コンストラクター内での参照について少し心配しています。this

より正確には、コンストラクターが終了する前に、参照がコンストラクターから外部に漏れてthisはなりません。そうしないと、外部パーティがまだ完成していない新しいオブジェクトのメソッドを呼び出すことになる可能性があります。

thisがマップに追加され、静的メソッドを介して外部の関係者がアクセスできるため、実装でこれが発生する可能性がありますgetInstance。救済策は、マップへのアクセスを同期することです。別のオプション (Effective Java で Josh Bloch が説明したように) は、具体的なサブクラスのコンストラクターをプライベートにし、代わりに各サブクラスに静的ファクトリ メソッドを配置して、オブジェクトを構築し、それをマップに追加することです。ただし、これによりコードの重複が発生します。

あなたのデザインについて

どうやら「製品の工場」ではなく「工場のカタログ」を実装しているため、これは従来のAbstract Factoryとはかなり異なります。詳細がなければ、これが正当化されるかどうかを判断するのは困難です。

主な問題は、ここでファクトリ インターフェイスとファクトリの「ストレージ」を統合することです。これは IMO ではありません。ファクトリのクライアントは、そのメソッドを含むファクトリ インターフェイスのみを表示する必要があり、実際に使用している具体的なファクトリを認識しないでください (自分で選択するgetXことははるかに少ない)。

さらに、通常、特定の時点で使用される具体的な製品ファミリは 1 つだけなので、必要な具体的な種類のファクトリは 1 つだけです。これにより、異なるコンクリート製品ファミリーの互換性のない製品を混同する可能性がなくなります。あなたの現在の設計はこれを許可しているようですが、これは私にとって良い兆候ではありません-しかし、おそらくあなたにはこれには正当な理由があります...

于 2010-07-01T16:00:11.933 に答える