javaoopdesign-patternspolymorphismfactory-method

When should we use the factory method pattern? (instead of composition)


As per GOF book, Factory method pattern

Define an interface for creating an object, but let the subclasses decide which class to instantiate. Factory method lets a class defer instantiation to subclass.

Structure of the pattern

public abstract class Factory {
    public abstract IProduct createProduct();
    private void performCriticalJob(){
        IProduct product = createProduct();
        product.serve();
    }
    public void executeJob(){
        //some code
        performCriticalJob();
        //some more code
    }
}


public interface IProduct {
    public void serve();
}
  1. Factory needs an object (whose concrete class is not known or whose concrete class may change as per the different application type ) to perform a task.

  2. As it does not know which class to instantiate, one standard contract is set for the type of object needed, this contract is put in an Interface.

  3. Base factory class declares an abstract method to return an object of type as above defined interface. It lets subclasses decide and provide the implementation of object creation.

  4. For completion of the task it needs an object which it simply fetches by calling the abstract method.

Question Favour Composition over inheritance. Factory method above uses inheritance to get the concrete products. Also subclasses need to be implement the createProduct which will create and return the ConcreteProduct. Instead of Subclassing the Factory class, if abstract method is removed from it (which makes the Factory class as non abstract class). Now Factory class can be composed by the new classes and concrete product objects can be injected in it as below example.

To achieve the intent in the scenarios as defined by Factory method pattern why just normal polymorphism is not being used as below ? I know factory method pattern has something more which I am missing but going by the favouting composition over inheritance, i find the below way ,to solve the same problem in same scenario , a better way over the way as in Factory method. What is the advantage of Factory method over the method below ?

public abstract class PolymorphismWay {
    private void performCriticalJob(IProduct product){
        product.serve();
        //some code
    }
    public void executeJob(IProduct product){
        //some code
        performCriticalJob(product);
        //some more code
    }
}

Now instead of asking users to create child factory classes and returning the concrete object of product by implementing the createProduct method, users can directly provide the object of concrete classes implementing IProduct to executeJob.

[EDIT] Thanks for the answers and comments but same thought as expressed in comments and answers I also had which also brought some confusion. I studied the GOF factory method pattern. It has used an example of a Framework for applications creating documents of various types. My questions are doubts those arouse after this study.

The sites and blogs are based nothing but the reflection of the understanding which the authour has for the pattern, he / she may or maynot have read, understood the actual intent of the pattern. Understanding the classes is not the main objective. Design pattern should be studied considering what scenario and what problem comes for which the best solution following the good OOP principles ( or violating them the least and voilating them along with having a very good reason to do so). That best solution is the solution as explained by any design pattern. GOF is a standard book which explains it quite well. But still there are few gaps or doubts which is the main reason for this question.


Solution

  • I know factory method pattern has something more which I am missing but going by the favouting composition over inheritance, i find the below way ,to solve the same problem in same scenario

    There are several advantages that you get when using the Factory Method pattern instead of plain old composition as shown in your question :

    1. Separation of concerns and open-closed principle : You create one factory subclass for each related group of objects. This factory subclass is responsible for creating only those products that belong to a particular group. ABCProductFactory will only be concerned with creating ABCProduct1, ABCProduct2, etc. CDEProductFactory will only be concerned with creating CDEProduct1, CDEProduct2 and so on. For every new product group, you create a new subclass rather than modifying an existing class. If you went with the composition approach, some other class would be responsible for creating the product and passing it into your Factory. As your product variety increases to say ZZZProduct1 and ZZZProduct2 and so on, this class would soon explode to a huge size with too many if-else conditions to check which product subclass to create. You would eventually realize this and define one class for creating each related group of products.

    2. Product creation and product processing has a contract : The factory method pattern is very similar to the template-method pattern in this case as it specifies a template for the operations that need to be performed on an object after it has been created. This allows you to ensure that once a product is created, it will always go through the same steps as any other product created by the factory. Compare this to the Composition example in your question where there is no fixed contract for what steps an IProduct should go through once it has been created. I could create a class called Factory2 with a single public method called performCriticalJob. Nothing forces me to have an executeJob method in Factory2. Even if I add an executeJob method to Factory2, nothing forces me to call performCriticalJob inside executeJob. You could fix this issue by using the template pattern.

    It should be clear by now that the Factory Method pattern basically binds the object creation and object processing together in one class. With your composition example, you would have a lot of moving pieces and no one governing how they should work together.

    Bottom line : In your case, use the Factory Method pattern when you want object creation and object processing to have a fixed contract such that all objects go through the same processing once created. Use your composition example where there is no contract needed for the steps to be followed after the object has been created.