Factory Pattern: Attaches additional responsibilities to an object dynamically and
provide a flexible alternative to subclassing for extending
functionality.
.
Often when you have a set of related classes you are forced to write code like this:.
Animal animal;
if(wood){
animal = new Bear();
}else if(sea){
animal = new Fish();
}else if(home){
animal = new Dog();
}
With code like this, you know that later on, when things have to be changed or extended you will have to reopen this code and check what has to be added or deleted. If this code ends up in several parts of your application maintenance and updates become cumbersome and error-prone. This can be solved using Factories - handling the details of object creation. Any time another class needs e.g. an animal, it asks the animal factory to create one.
Simple Factory & Static Factory
Encapsulating this object creation process in its own class we get a simple factory. We now have only one place to where we can implement changes. If you define this simple factory as static you get a static factory - advantage: no need to instantiate an object - disadvantage: can't subclass and change behavior.
public class SimpleAnimalFactory{
public Animal createAnimal(String type){
Animal animal;
if(type.equals("wood")){
animal = new Bear();
}else if(type.equals("sea")){
animal = new Fish();
}else if(type.equals("home")){
animal = new Dog();
}
return animal;
}
}
This simple factory isn't an actual design pattern (more like an idiom) - still it is commonly used. Simple factories do not give you control over what should happen after an object was instantiated. The next two real factory patterns give you a little bit more 'quality control'.
Factory Method Pattern: A factory mehtod handles object creation and encapsulates it in
a subclass. This decouples the client code in the superclass
from the object creation code in the subclass.
a subclass. This decouples the client code in the superclass
from the object creation code in the subclass.
The factory method pattern lets subclasses decide which objects should be created, but specyfies other processes which should stay the same among all subclasses. Imagine a pizza franchise where each pizza shop can decide for a regional pizza style. Still the order system should stay the same for each shop.
public abstract class PizzaStore{
public Pizza orderPizza(String type){
Pizza pizza = createPizza(type);
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
abstract Pizza createPizza(String type);
}
Now each pizza shop may implement its own createPizza method, e.g., the Austrian pizza shop creates AustrianStyleCheesePizza, while the American pizza shop creates AmericanSyleCheesePizza.if(type.equals("cheese")){ animal = new
AustrianStyleCheesePizza(); }
if(type.equals("cheese")){ animal = new
AmericanStyleCheesePizza
(); }
The abstract class PizzaStore does a lot of things with a Pizza object, but because Pizza is abstract it has no idea what real concrete classes are involved - it is decoupled. With this simple transformations we have gone from having an object handling the instantiation of concrete classes (simple factory) to a set of subclasses that take on that responsibility.
The factory method pattern defines an interface for creating an object, but lets subclasses decide which class to instantiate. Factory method lets a class defer instantiation to subclasses.
(factory method uml) |
Advantages:
- By placing all creation code in one object or method, code duplication is avoided and you provide one place to perform maintenance.
- Clients depend only upon interfaces rather than concrete classes required to instantiate objects (programming to an interface - more flexible, extensible).
The factory method pattern makes use of the dependency inversion principle (Check out all other design principles in this post OO principles):
Design Principle 6: Depend upon abstractions. Do not depend upon concrete classes. It suggests that our high-level components (PizzaStore) should not dpend on our low-level components (ConcretePizza).
In our factory method pattern example both the high-level component PizzaStore and the low-level components concrete pizzas depend on Pizza, the abstraction.
Next post: Abstract Factory Pattern
No comments:
Post a Comment