Reputation: 163
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?
Upvotes: 6
Views: 794
Reputation: 2901
In Simple Factory, you write a class, which provides very powerful encapsulation, but to do only one thing: encapsulating the creation and underlying type of an object. While, Factory Method pattern takes the full advantage of this class: it does what Simple Factory does, besides, it also encapsulates the create-process to not only create a "raw new object", but an deliverable / fully-equipped result, that's why it called orderProduct
not just createProduct
.
In short, the point of Factory Method is method that uses a Simple Factory. So if you think Factory Method is less flexible, that's because Factory Method does more things!
Upvotes: 0
Reputation: 726619
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
}
}
Upvotes: 3