I was reading design patterns from a website
There I read about Factoy
, Factory method and Abstract factory but they are so confusing, am not clear on the definition. According to definitions
Factory - Creates objects without exposing the instantiation logic to the client and Refers to the newly created object through a common interface. Is a simplified version of Factory Method
Factory Method - Defines an interface for creating objects, but let subclasses to decide which class to instantiate and Refers to the newly created object through a common interface.
Abstract Factory - Offers the interface for creating a family of related objects, without explicitly specifying their classes.
I also looked the other stackoverflow threads regarding Abstract Factory vs Factory Method but the UML diagrams drawn there make my understanding even worse.
Can anyone please tell me
- How are these three patterns different from each other?
- When to use which?
- And also if possible, any java examples related to these patterns?
All three Factory types do the same thing: They are a “smart constructor”.
Let’s say you want to be able to create two kinds of Fruit: Apple
and Orange
.
Factory
Factory is “fixed”, in that you have just one implementation with no subclassing. In this case, you will have a class like this:
class FruitFactory {
public Apple makeApple() {
// Code for creating an Apple here.
}
public Orange makeOrange() {
// Code for creating an orange here.
}
}
Use case: Constructing an Apple
or an Orange
is a bit too complex to handle in the constructor for either.
Factory Method
Factory method is generally used when you have some generic processing in a class, but want to vary which kind of fruit you actually use. So:
abstract class FruitPicker {
protected abstract Fruit makeFruit();
public void pickFruit() {
private final Fruit f = makeFruit(); // The fruit we will work on..
<bla bla bla>
}
}
…then you can reuse the common functionality in FruitPicker.pickFruit()
by implementing a factory method in subclasses:
class OrangePicker extends FruitPicker {
@Override
protected Fruit makeFruit() {
return new Orange();
}
}
Abstract Factory
Abstract factory is normally used for things like dependency injection/strategy, or if you want to be able to create a whole family of objects that need to be of “the same kind”, yet have some common base classes. Here’s a vaguely fruit-related example. The use case here is that we want to make sure that we don’t accidentally use an OrangePicker
on an Apple
. As long at we get our Fruit
and Picker
from the same factory, they will match.
interface PlantFactory {
Plant makePlant();
Picker makePicker();
}
public class ApplePicker implements PlantFactory {
Plant makePlant() {
return new Apple();
}
Picker makePicker() {
return new ApplePicker();
}
}
public class OrangePicker implements PlantFactory {
Plant makePlant() {
return new Orange();
}
Picker makePicker() {
return new OrangePicker();
}
}