Your comments

This summaries the issue I had when using the abstract factory pattern and possibly similar to your issue in your other forum post, my client code needed to create similarly structured products from every file within a directory based on their name.

The files had standardised names and standardised file suffixes, e.g. fileA.txt, fileB.txt, fileA.pdf, fileB.pdf... so on. in any order and any number.

Instead of using the client to implement a for loop which directly created instances of the exact product associated with the exact file... you can create a factory for the each of the variables with the least variation (in my case the file suffixes). These factories themselves are an instance of an Abstract Factory Class, and they all implement methods which create products based on the file name.

This way the client code does have a decision to make, but its quite a simple for loop. Now, only one variable is filtered by the client to the correct factory. The correct factory uses the remaining variable (in this case, file name) to decide which product creation method to use. Product creation incidentally needed some extra logic related to the contents of the file, and this could also be handled by the factory pre or post product creation, but before handing the product back to the client.

pseudo_code something like:

folder = [file1.txt, file2.txt, file3.txt, file1.pdf, file2.pdf, file3.pdf]

client_create_products(folder):

    for i in folder:

       if i.suffix == txt

           txt_factory.filter_name(file.stem)

# The filter_name method internally calls a create_product() only after it decides which one to use

   elif i.suffix == pdf

            pdf_factory.filter_name(file.stem)

If there are many variables that decide which factory and product to create, you could always create a factory factory and sequentially pass variables down the line... but I'm not sure how many levels of recursion would be acceptable lol. Although with this method you can handle exceptions before or after product creation and at the appropriate level  without breaking the initial loop!