Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is the Factory Method Pattern more flexible than Simple Factory?

I've been reading the book Head First: Design Patterns, which I have found to be a good introduction to design patterns. However, I've got a question about a claim they make in Chapter 4:

They define the "Simple Factory" pattern as follows (Java pseudocode):

public abstract class Product
{
// Product characteristics
// Concrete Products should subclass this    
}
public class SimpleFactory {
    public Product createProduct(){
        // Return an instance of some subclass of Product
    }
}
public class Store {
    SimpleFactory factory;
    public Product orderProduct(){
        Product product = factory.createProduct();
        // Do some manipulation on product
        return product;
    }
}

The "Factory Method" is defined as follows (class Product remains the same and is omitted):

public abstract class Store {
//Concrete Stores must subclass this and override createProduct()
    public abstract Product createProduct();

    public Product orderProduct(){
        Product product = createProduct();
        // Do some manipulation on product
        return product;
    } 
}

Then the authors go on to claim that the Factory Method Pattern is much more flexible than Simple Factory, because while Simple Factory is "a one shot deal, with Factory Method you are creating a framework that lets the subclasses decide which implementation should be used" (page 135).

Now I don't get why this is true. The way I see it, Simple Factory is, in some senses, slightly more flexible than Factory Method: you can subclass the Simple Factory (instead of subclassing the Store) to get essentially the same behavior. You can even change the behavior at runtime if you wish! The only disadvantage of Simple Factory I could think of is when the product creation depends on state variables of the Store class: is this what the authors are calling flexibility, or am I missing something?

like image 900
Pedro M. Avatar asked Oct 22 '14 15:10

Pedro M.


People also ask

What is the difference between the factory method and a simple factory?

Use the Factory method when you want to make a Framework where you want to take a control from the creation of the Object to the management of that Object. That's unlike the Simple factory, where you only care about the creation of a product, not how to create and manage it.

What is difference between factory method and factory pattern?

The factory method is a creational design pattern, i.e., related to object creation. In the Factory pattern, we create objects without exposing the creation logic to the client and the client uses the same common interface to create a new type of object.

What is the advantage of factory pattern?

Advantage of Factory Design Pattern Factory Method Pattern allows the sub-classes to choose the type of objects to create. It promotes the loose-coupling by eliminating the need to bind application-specific classes into the code.


1 Answers

You are absolutely right: author's assumption has been that you are not going to subclass SimpleFactory, which is not a fair assumption to make (unless SimpleFactory is marked final).

Since SimpleFactory is not final, you can definitely subclass it, gaining more flexibility than with a factory method, because SimpleFactory replaces inheritance with composition.

An even better approach would be making SimpleFactory an interface. Doing so would let you pick composition or inheritance according to your preference, because an interface would not limit you in cases when your Store class already inherits a class.

public interface SimpleFactory {
    Product createProduct();
}

Then you can use either composition

public class FactoryImpl implements SimpleFactory {
    public Product createProduct(){
        // Return an instance of some subclass of Product
    }
}
public class StoreComposition {
    SimpleFactory factory = new FactoryImpl();
}

or inheritance/composition combo

public class StoreInheritance implements SimpleFactory {
    SimpleFactory factory = this;
    public Product createProduct(){
        // Return an instance of some subclass of Product
    }
}
like image 58
Sergey Kalinichenko Avatar answered Sep 24 '22 20:09

Sergey Kalinichenko