Abstract Factoryは問題なく拡張できます。
クラスは一つのことをうまくやるべきだと述べている基本原則があります。ここでの問題は、多くのクラスに多くのことを実行させようとしていることです。
1つの抽象ファクトリに固執する必要はありません。あなたはいくつかのことができます(そして持っているべきです):
AbstractProductAFactoryProductAを作成するためのインターフェースを定義します。具体的な実装(ConcreteProductAFactory1、ConcreteProductAFactory2)はそれを拡張します。
AbstractProductBFactoryProductBを作成するためのインターフェースを定義します。具体的な実装(ConcreteProductBFactory1、ConcreteProductBFactory2)はそれを拡張します。
次にProductCが必要な場合は、新しいを作成しますAbstractProductCFactory。この方法で他の工場を変更する必要はありません。
UPDATE
理想的には、ProductAは製品のクラス、つまり、ProductAと呼んでいるインターフェースを共有するすべての製品を表す必要があります。コメントで私はこれがピザのようなものであることを提案します:
interface AbstractPizzaFactory {
public Pizza buildPizza(List<Topping> toppings);
}
class ThinCrustPizzaFactory implements AbstractPizzaFactory {
public Pizza buildPizza(List<Topping> toppings){
...
}
}
class DeepDishPizzaFactory implements AbstractPizzaFactory {
public Pizza buildPizza(List<Topping> toppings){
...
}
}
等々。PanPizzaFactoryを追加しても、他のクラスには影響しません。これは、PizzaFactoryの新しい具体的な実装にすぎません。ピザではない製品(サンドイッチなど)がある場合、そこに別の抽象ファクトリ(たとえばAbstractSandwichFactory)を作成します。
実際のポイントは、2つの異なる「ビルド」メソッドを使用して2種類の非常に異なるタイプの製品をビルドする抽象ファクトリーは必要ないということです。それらをできるだけ論理的にグループ化して、インターフェースを共有し、具体的なファクトリーがそのインターフェースの実装を構築する方法を定義する抽象ファクトリーを作成します。