Factory Pattern

  • Creates objects without specifying the exact class to create.

Lets say we have an Pizza Store and we need to sell different types of Pizza:

public class PizzaStore {

    public Pizza orderPizza() {
        Pizza pizza = new CheesePizza();

        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();

        return pizza; 
    }

}

What happens when you need to sell more than one type of Pizza:

public Pizza orderPizza(String type) {

    Pizza pizza = null;

    if (type.equals("cheese")){
        pizza = new CheesePizza(); 
    } else if(type.equals("greek")){
        pizza = new GreekPizza(); 
    } else if(type.equals("pepperoni")){
        pizza = new PepperoniPizza(); 
    }

    pizza.prepare();
    pizza.bake();
    pizza.cut();
    pizza.box();

    return pizza; 

}

public interface Pizza {

    void prepare(); 
    void bake();
    void cut();
    void box();
}

public class CheesePizza implements Pizza {

    public void prepare() {
        //get cheese
        //get parmesan 
    }

    void bake() {
        //melt cheese  
    }
}

public class VegetarianPizza implements Pizza {

    public void prepare() {
        //get tomato
        //get egg mayo 
    }

    void bake() {
        //chop tomato  
    }

}


Pizza cheesePizza = new CheesePizza(); 
Pizza veggiePizza = new VegetarianPizza();

What is the problem?

  • Code is not closed for modification, if we need to add more pizza, we need to modify the PizzaShop

How do we solve it?

  • Move the object creations (new CheesePizza(), new PepperoniPizza()) out of the orderPizza method().
  • Place it in something called a Factory
public PizzaFactory {
    public static Pizza createPizza(String type) {
        Pizza pizza = null;
        if (type.equals("cheese")){
            pizza = new CheesePizza(); 
        } else if(type.equals("greek")){
            pizza = new GreekPizza(); 
        } else if(type.equals("pepperoni")){
            pizza = new PepperoniPizza(); 
        } else if(type.equals("vegetarian")){ //Easily add new Pizza 
            pizza = new VeggiePizza(); 
        }
        return pizza; 
    }
}

How does the PizzaStore looks like now?

public class PizzaStore {

    public Pizza orderPizza(String type) {
        Pizza pizza = PizzaFactory.createPizza(type);

        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();

        return pizza; 
    }

}

What is the advantage of this pattern?

  • Now we only need to make modification in the PizzaFactory when implementation changes
  • We can reuse this Factory in a different class eg: HomeDelivery

In a real case scenario we can use it for creating different type of NotificationService:

public interface NotificationService {

    boolean send(Message message);

}

public class EmailNotificationService implements NotificationService {

    boolean send(Message message) {
        //Implementation
        //SMTP SERVER GMAIL
    }

}

public class SMSNotificationService implements NotificationService {

    boolean send(Message message) {
        //Implementation
        //TWILIO WHISPIR 
    }

}

Factory:

public class NotificationFactory {

    public static createNotificationService(String type) {
        if (type.equals("EMAIL")){
            return new EmailNotificationService(); 
        } else if(type.equals("SMS")){
            return new SMSService(); 
        } else {
            throw IllegalArgumentException(); 
        }       
    }
}

results matching ""

    No results matching ""