Abstract Factory escala muy bien.
Hay un principio básico que establece que una clase debe hacer una cosa bien. Su problema aquí es que está tratando de hacer que muchas clases hagan muchas cosas.
No tiene que atenerse a una fábrica abstracta. Puede (y debe tener) varios:
AbstractProductAFactorydefine la interfaz para producir ProductA. Sus implementaciones concretas (ConcreteProductAFactory1, ConcreteProductAFactory2) lo ampliarían.
AbstractProductBFactorydefine la interfaz para producir ProductB. Sus implementaciones concretas ( ConcreteProductBFactory1, ConcreteProductBFactory2) lo ampliarían.
Si necesita un ProductC, cree uno nuevo AbstractProductCFactory. No es necesario cambiar ninguna de sus otras fábricas de esta manera.
ACTUALIZACIÓN
Idealmente, ProductA debería representar una clase de producto, es decir, todos los productos que comparten una interfaz que está llamando ProductA. En los comentarios sugiero que esto es algo así como una pizza:
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){
...
}
}
Y así. Agregar una PanPizzaFactory no afectará a ninguna de las otras clases: es solo una nueva implementación concreta de PizzaFactory. Si tiene productos que no son pizzas, por ejemplo, sándwiches, allí es donde crea otra fábrica abstracta (por ejemplo, AbstractSandwichFactory).
El punto real es que no querrás tener una fábrica abstracta que construya dos tipos muy diferentes de productos con dos métodos diferentes de "compilación". Agrúpelos lo más lógicamente posible para que compartan una interfaz, y luego cree una fábrica abstracta que defina cómo las fábricas concretas deben construir implementaciones de esa interfaz.