The Abstract Factory Pattern, like the other Factory Patterns, encapsulates object creation. The Abstract Factory Pattern provides an interface for creating families of related or dependant objects without specifying their concrete classes. This Pattern allows a client to use an abstract interface to create a set of related products without knowing (or caring) about the concrete products that are actually produced. In this way the client is decoupled from any of the specifics of the concrete products.
An example of the Abstract Factory Design Pattern follows:
public interface PizzaIngredientFactory {
public Dough createDough();
public Sauce createSauce();
...
}
// The concrete classes produce a family of products (objects)
public class NYPizzaIngredientFactory implements PizzaIngredientFactory {
public Dough createDough() { return new ThinCrustDough(); }
public Sauce createSauce() { return new MarinaraSauce(); }
}
public class ChicagoPizzaIngedientFactory implements PizzaIngredientFactory {
public Dough createDough() { return new ThickCrustDough(); }
public Sauce createSauce() { return new PlumTomatoeSauce(); }
}
// new version from Factory Method Pattern
public class NYPizzaStore extends PizzaStore {
public Pizza createPizza(String type) {
Pizza pizza;
PizzaIngredientFactory factory = new NYPizzaIngredientFactory();
if (type.equals("cheese")) {
pizza = new CheesePizza(factory);
pizza.setName("NY Style Cheese Pizza");
}
if (type.equals("pepperoni")) {
pizza = new PepperoniPizza(factory);
}
if (type.equals("veggie")) {
pizza = new VeggiePizza(factory):
}
return pizza;
}
}
public abstract class Pizza {
String name;
Dough dough;
Sauce sauce;
...
abstract void prepare();
void bake();
void cut();
...
}
// concrete class using factory passed in.
// Similar for PepperoniPizza, VeggiePizza, etc.
public class CheesePizza extends Pizza {
PizzaIngredientFactory factory;
public CheesePizza(PizzaIngredientFactory ingredientFactory) {
factory = ingredientFactory;
}
void prepare() {
dough = factory.createDough();
sauce = factory.createSauce();
...
}
}