By Irwan Fathurrahman
Order Burger

prepare

bake

presentation

filling
Public Burger orderBurger(){
Burger burger = new Burger();
burger.prepare();
burger.bake();
burger.filling();
burger.presentation();

Our store can take
and give the order.
This is the simple way
for our function to
take order based of
strategy in previous
slide

return burger;

}
But our store just have
one kind of Burger!
We have to create 4 menu!
Public Burger orderBurger(String type){
Burger burger;
if(type == “cheese”){
burger = new CheeseBurger();
} else if(type == “double cheese”){
burger = new DoubleCheeseBurger();
} else if(type == “beef”){
burger = new BeefBurger();
} else if(type == “doublebeef”){
burger = new DoubleBeefBurger();
}

That it!
Our store can take 4
kind of Burger.
- Cheese Burger
- Double Cheese
Burger
- Beef Burger
- Double Beef Burger

burger.prepare();
burger.bake();
burger.filling();
burger.presentation();
return burger;
}
But! What about we
add new burger and
remove old Burger?
Public Burger orderBurger(String type){
Burger burger;
if(type == “cheese”){
burger = new CheeseBurger();
} else if(type == “double cheese”){
burger = new DoubleCheeseBurger();
} else if(type == “beef”){
burger = new BeefBurger();
} else if(type == “doublebeef”){
burger = new DoubleBeefBurger();
} else if(type == “chesse&beef”){
burger = new CheeseBeefBurger();
}

It mess our order
burger method and
make order burger
closed modification

burger.prepare();
burger.bake();
burger.filling();
burger.presentation();
return burger;
}
SOLUTION! -> simple factory
Make simple factory that can
produce one kind burger.

Public class BurgerStore{
BurgerFactory factory;
Public BurgerStore(BurgerFactory factory){
this.factory = factory;
}
Public Burger orderBurger(String type){
Burger burger = factory.createBurger(type);
burger.prepare();
burger.bake();
burger.filling();
burger.presentation();

Public class BurgerFactory{
return burger;
Public Burger createBurger(String type){
Burger burger;
if(type == “cheese”){
burger = new CheeseBurger();
} else if(type == “beef”){
burger = new BeefBurger();
} else if(type == “doublebeef”){
burger = new DoubleBeefBurger();
} else if(type == “chesse&beef”){
burger = new CheeseBeefBurger();
}
return burger;

}
}

}

}
Now, we can sell our Burgers!
Oh Look! Our store expands!
Now we have 2 store, but have different menu
Back to old solution?
Because our both store have different menu, we can’t
have same factory
Add 2 factory
- It can be a solution. Each store can choose their own factory.
- But if other store share one factory and suddenly add their own menu, it
can be a problem later.

Public class BurgerFactoryStore1{

Public class BurgerFactoryStore2{

Public Burger createBurger(String type){
Burger burger;

Public Burger createBurger(String type){
Burger burger;

if(type == “cheese”){
burger = new CheeseBurger();
} else if(type == “beef”){
burger = new BeefBurger();
} else if(type == “doublebeef”){
burger = new DoubleBeefBurger();
} else if(type == “chesse&beef”){
burger = new CheeseBeefBurger();
}

if(type == “cheese”){
burger = new CheeseBurger();
} else if(type == “doublecheese”){
burger = new DoubleCheeseBurger();
} else if(type == “beef”){
burger = new BeefBurger();
} else if(type == “doublebeef”){
burger = new DoubleBeefBurger();
}
return burger;

return burger;

}
}

}

}
Solution?
What about we make every store decide their own
menu?
SOLUTION! -> factory method

Public class Store1 extends BurgerStore{
Public Burger createBurger(String type){
Burger burger;

We just make interface for our store, but
they can decide their own menu.

Public abstract class BurgerStore{
BurgerFactory factory;

if(type == “cheese”){
burger = new CheeseBurger();
} else if(type == “beef”){
burger = new BeefBurger();
}
return burger;
}
}

Public BurgerStore(BurgerFactory factory){
this.factory = factory;
}
Public Burger orderBurger(String type){
Burger burger = createBurger(type);

Public class Store2 extends BurgerStore{
Public Burger createBurger(String type){
Burger burger;

burger.prepare();
burger.bake();
burger.filling();
burger.presentation();

if(type == “beef”){
burger = new BeefBurger();
} else if(type == “doublebeef”){
burger = new DoubleBeefBurger();
}
return burger;

return burger;
}
Public abstract Burger createBurger
(String type);
}

}
}
But we have other problem!
Customer want other style of vegetable and beef too.
Look our Burger

One of our kind of Burger

Public abstract class Burger{
Beef factory;
Vegetable vegetable;
Public abstract void prepare();
Public void bake(){
// some method
}
Public void filling(){
// some method
}

Public class ChesseBburger extends Burger{
Public void ChesseBburger(// need ingredient){

Public void presentation(){
// some method
}

}
}
Public void prepare(){};
}
This our ingredient creator
Public interface IngredientFactory {

Need ingredient factory that create
beef and vegetable

Public class IndonesianBurgerIngredientFactory {

Public Beef createBeef();
Public Vegetable createVegetable();
}

Public class JapaneseBurgerIngredientFactory {

Public Beef createBeef(){
return new SapiLadaHitam();
}
Public Vegetable createVegetable(){
return new Kangkung();
}
}

Public Beef createBeef(){
return new FreshFish();
}
Public Vegetable createVegetable(){
return new Nori();
}
}
Solution! -> Abstract Factory Method
Now we can take ingredient style
customer want without affecting
our method in burger.

Public class ChesseBburger extends Burger{
IngredientFactory ingredient;
Public void ChesseBburger(
IngredientFactory ingredient){
this.Ingredient = ingredient;
}
Public void prepare(){
ingredient.createBeef();
ingredient.createVegetable();
};

Public class Store1 extends BurgerStore{
Public Burger createBurger(String type,
IngredientFactory ingredient){
Burger burger;
if(type == “cheese”){
burger = new CheeseBurger(ingredient);
} else if(type == “beef”){
burger = new BeefBurger(ingredient);
}
return burger;
}
}

}
Review
Simple factory is a simple way to decouple our
client from concrete class.
 Factory Method relies on inheritance : object
creation is delegated to subclasses which
implement the factory method to create object.
 Abstract factory Method relies on object
composition : ocject creation is implemented in
method exposed in factory interface.

Review


All factory pattern promote loose coupling by
reducing the depedency on concrete class.

Concrete class is class which will be
an object concrete.
Design Pattern




Is a description or template for how to solve a
problem that can be used in many different
situations.
Design patterns are optimized, reusable solutions
to the programming problems that we encounter
every day.
Design Principle



Take the parts that vary and encapsulate them.
So, we can can alter or extend that vary later
without affecting those that don’t.
Design Principle


Code for an interface, not code for and
implementation.
Design Principle


Depend upon abstraction, don’t upon concrete
class.

Design Pattern with Burger

  • 1.
  • 3.
  • 4.
    Public Burger orderBurger(){ Burgerburger = new Burger(); burger.prepare(); burger.bake(); burger.filling(); burger.presentation(); Our store can take and give the order. This is the simple way for our function to take order based of strategy in previous slide return burger; }
  • 5.
    But our storejust have one kind of Burger! We have to create 4 menu!
  • 6.
    Public Burger orderBurger(Stringtype){ Burger burger; if(type == “cheese”){ burger = new CheeseBurger(); } else if(type == “double cheese”){ burger = new DoubleCheeseBurger(); } else if(type == “beef”){ burger = new BeefBurger(); } else if(type == “doublebeef”){ burger = new DoubleBeefBurger(); } That it! Our store can take 4 kind of Burger. - Cheese Burger - Double Cheese Burger - Beef Burger - Double Beef Burger burger.prepare(); burger.bake(); burger.filling(); burger.presentation(); return burger; }
  • 7.
    But! What aboutwe add new burger and remove old Burger?
  • 8.
    Public Burger orderBurger(Stringtype){ Burger burger; if(type == “cheese”){ burger = new CheeseBurger(); } else if(type == “double cheese”){ burger = new DoubleCheeseBurger(); } else if(type == “beef”){ burger = new BeefBurger(); } else if(type == “doublebeef”){ burger = new DoubleBeefBurger(); } else if(type == “chesse&beef”){ burger = new CheeseBeefBurger(); } It mess our order burger method and make order burger closed modification burger.prepare(); burger.bake(); burger.filling(); burger.presentation(); return burger; }
  • 9.
    SOLUTION! -> simplefactory Make simple factory that can produce one kind burger. Public class BurgerStore{ BurgerFactory factory; Public BurgerStore(BurgerFactory factory){ this.factory = factory; } Public Burger orderBurger(String type){ Burger burger = factory.createBurger(type); burger.prepare(); burger.bake(); burger.filling(); burger.presentation(); Public class BurgerFactory{ return burger; Public Burger createBurger(String type){ Burger burger; if(type == “cheese”){ burger = new CheeseBurger(); } else if(type == “beef”){ burger = new BeefBurger(); } else if(type == “doublebeef”){ burger = new DoubleBeefBurger(); } else if(type == “chesse&beef”){ burger = new CheeseBeefBurger(); } return burger; } } } }
  • 10.
    Now, we cansell our Burgers!
  • 11.
    Oh Look! Ourstore expands! Now we have 2 store, but have different menu
  • 12.
    Back to oldsolution? Because our both store have different menu, we can’t have same factory
  • 13.
    Add 2 factory -It can be a solution. Each store can choose their own factory. - But if other store share one factory and suddenly add their own menu, it can be a problem later. Public class BurgerFactoryStore1{ Public class BurgerFactoryStore2{ Public Burger createBurger(String type){ Burger burger; Public Burger createBurger(String type){ Burger burger; if(type == “cheese”){ burger = new CheeseBurger(); } else if(type == “beef”){ burger = new BeefBurger(); } else if(type == “doublebeef”){ burger = new DoubleBeefBurger(); } else if(type == “chesse&beef”){ burger = new CheeseBeefBurger(); } if(type == “cheese”){ burger = new CheeseBurger(); } else if(type == “doublecheese”){ burger = new DoubleCheeseBurger(); } else if(type == “beef”){ burger = new BeefBurger(); } else if(type == “doublebeef”){ burger = new DoubleBeefBurger(); } return burger; return burger; } } } }
  • 14.
    Solution? What about wemake every store decide their own menu?
  • 15.
    SOLUTION! -> factorymethod Public class Store1 extends BurgerStore{ Public Burger createBurger(String type){ Burger burger; We just make interface for our store, but they can decide their own menu. Public abstract class BurgerStore{ BurgerFactory factory; if(type == “cheese”){ burger = new CheeseBurger(); } else if(type == “beef”){ burger = new BeefBurger(); } return burger; } } Public BurgerStore(BurgerFactory factory){ this.factory = factory; } Public Burger orderBurger(String type){ Burger burger = createBurger(type); Public class Store2 extends BurgerStore{ Public Burger createBurger(String type){ Burger burger; burger.prepare(); burger.bake(); burger.filling(); burger.presentation(); if(type == “beef”){ burger = new BeefBurger(); } else if(type == “doublebeef”){ burger = new DoubleBeefBurger(); } return burger; return burger; } Public abstract Burger createBurger (String type); } } }
  • 16.
    But we haveother problem! Customer want other style of vegetable and beef too.
  • 17.
    Look our Burger Oneof our kind of Burger Public abstract class Burger{ Beef factory; Vegetable vegetable; Public abstract void prepare(); Public void bake(){ // some method } Public void filling(){ // some method } Public class ChesseBburger extends Burger{ Public void ChesseBburger(// need ingredient){ Public void presentation(){ // some method } } } Public void prepare(){}; }
  • 18.
    This our ingredientcreator Public interface IngredientFactory { Need ingredient factory that create beef and vegetable Public class IndonesianBurgerIngredientFactory { Public Beef createBeef(); Public Vegetable createVegetable(); } Public class JapaneseBurgerIngredientFactory { Public Beef createBeef(){ return new SapiLadaHitam(); } Public Vegetable createVegetable(){ return new Kangkung(); } } Public Beef createBeef(){ return new FreshFish(); } Public Vegetable createVegetable(){ return new Nori(); } }
  • 19.
    Solution! -> AbstractFactory Method Now we can take ingredient style customer want without affecting our method in burger. Public class ChesseBburger extends Burger{ IngredientFactory ingredient; Public void ChesseBburger( IngredientFactory ingredient){ this.Ingredient = ingredient; } Public void prepare(){ ingredient.createBeef(); ingredient.createVegetable(); }; Public class Store1 extends BurgerStore{ Public Burger createBurger(String type, IngredientFactory ingredient){ Burger burger; if(type == “cheese”){ burger = new CheeseBurger(ingredient); } else if(type == “beef”){ burger = new BeefBurger(ingredient); } return burger; } } }
  • 20.
    Review Simple factory isa simple way to decouple our client from concrete class.  Factory Method relies on inheritance : object creation is delegated to subclasses which implement the factory method to create object.  Abstract factory Method relies on object composition : ocject creation is implemented in method exposed in factory interface. 
  • 21.
    Review  All factory patternpromote loose coupling by reducing the depedency on concrete class. Concrete class is class which will be an object concrete.
  • 22.
    Design Pattern   Is adescription or template for how to solve a problem that can be used in many different situations. Design patterns are optimized, reusable solutions to the programming problems that we encounter every day.
  • 23.
    Design Principle   Take theparts that vary and encapsulate them. So, we can can alter or extend that vary later without affecting those that don’t.
  • 24.
    Design Principle  Code foran interface, not code for and implementation.
  • 25.
    Design Principle  Depend uponabstraction, don’t upon concrete class.