the abstract factory pattern and singleton patternjin/3132/lectures/dp-08.pdf · 2011-07-14 · the...

32
The Abstract Factory Pattern and Singleton Pattern CSCI 3132 Summer 2011 1

Upload: others

Post on 05-Jun-2020

6 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: The Abstract Factory Pattern and Singleton Patternjin/3132/lectures/dp-08.pdf · 2011-07-14 · The Abstract Factory Pattern and Singleton Pattern CSCI 3132 Summer 2011 1

The Abstract Factory Pattern and

Singleton Pattern

CSCI 3132 Summer 2011 1

Page 2: The Abstract Factory Pattern and Singleton Patternjin/3132/lectures/dp-08.pdf · 2011-07-14 · The Abstract Factory Pattern and Singleton Pattern CSCI 3132 Summer 2011 1

Simple  Factory  Pa0ern  

Client orderProduct()

SimpleFactory createProduct()

<<abstract>> Product

productMethod()

ConcreteProductB

ConcreteProductA

ConcreteProductC

2

Page 3: The Abstract Factory Pattern and Singleton Patternjin/3132/lectures/dp-08.pdf · 2011-07-14 · The Abstract Factory Pattern and Singleton Pattern CSCI 3132 Summer 2011 1

Factory  Method  Structure  

3

Page 4: The Abstract Factory Pattern and Singleton Patternjin/3132/lectures/dp-08.pdf · 2011-07-14 · The Abstract Factory Pattern and Singleton Pattern CSCI 3132 Summer 2011 1

Creator  Class  

4

Page 5: The Abstract Factory Pattern and Singleton Patternjin/3132/lectures/dp-08.pdf · 2011-07-14 · The Abstract Factory Pattern and Singleton Pattern CSCI 3132 Summer 2011 1

Product  Class  

5

Page 6: The Abstract Factory Pattern and Singleton Patternjin/3132/lectures/dp-08.pdf · 2011-07-14 · The Abstract Factory Pattern and Singleton Pattern CSCI 3132 Summer 2011 1

Advantage  

•  The  Creator  (PizzaStore)  is  not  ?ghtly  coupled  to  any  concrete  product  (Pizza).  

•  Instan?a?ng  concrete  classes  is  an  area  of  frequent  change.  By  encapsula?ng  it  using  factories  we  avoid  code  duplica?on  (which  is  a  code  smell)  and  make  it  easier  to  embrace  change  during  development  or  to  perform  maintenance.  

•  The  Factory  Pa0ern  also  illustrate  the  principle  of  coding  to  abstrac?ons  (the  Pizza  product  and  the  PizzaStore  client  are  abstracts)  

6

Page 7: The Abstract Factory Pattern and Singleton Patternjin/3132/lectures/dp-08.pdf · 2011-07-14 · The Abstract Factory Pattern and Singleton Pattern CSCI 3132 Summer 2011 1

•  This  is  possibly  a  development  and  maintenance  nighmare  

7

Page 8: The Abstract Factory Pattern and Singleton Patternjin/3132/lectures/dp-08.pdf · 2011-07-14 · The Abstract Factory Pattern and Singleton Pattern CSCI 3132 Summer 2011 1

•  This  is  what  the  Factory  Method  pa0ern  has  achieved:  

8

Page 9: The Abstract Factory Pattern and Singleton Patternjin/3132/lectures/dp-08.pdf · 2011-07-14 · The Abstract Factory Pattern and Singleton Pattern CSCI 3132 Summer 2011 1

The  Abstract  Factory  

•  Our  code  can  now  work  with  different  concrete  factories,    through  a  Factory  interface  (Pizzastore)  

• What  if  we  need  to  create  several  types  of  ”products”,  not  just  a  single  type?  – Pizza  dough  (  Thin  in  NY,  Thick  in  Chicago)    – Sauce  (…)  

9

Page 10: The Abstract Factory Pattern and Singleton Patternjin/3132/lectures/dp-08.pdf · 2011-07-14 · The Abstract Factory Pattern and Singleton Pattern CSCI 3132 Summer 2011 1

The  Abstract  Factory  

•  Answer  seems  simple:  just  use  Factory  Method  pa0ern  twice  

pizza dough

ThickCrustDough ThinCrustDough

pizza Sauce

PlumTomatoSauce MarinaraSauce

10

Page 11: The Abstract Factory Pattern and Singleton Patternjin/3132/lectures/dp-08.pdf · 2011-07-14 · The Abstract Factory Pattern and Singleton Pattern CSCI 3132 Summer 2011 1

The  Abstract  Factory  

•  This  looks  fine…  •  …but  does  it  reflect  our  inten?on?  • Would  it  make  sense  to  have  a  pizza,  with    

– Chicago  Thick  Crust  +  NY  Marinara  Sauce?    

• Model  does  not  include  any  ”binding”  between  related  products  

11

Page 12: The Abstract Factory Pattern and Singleton Patternjin/3132/lectures/dp-08.pdf · 2011-07-14 · The Abstract Factory Pattern and Singleton Pattern CSCI 3132 Summer 2011 1

The  Abstract  Factory  

•  A  Dough  and  a  Sauce  are  not  –  as  seen  from  a  type  point-­‐of-­‐view  –  related  

• Would  be  somewhat  ar?ficial  –  or  perhaps  even  impossible  –  to  introduce  a  common  base  class  

•  However,  we  can  enforce  the  binding  through  a  shared  factory  class!  

12

Page 13: The Abstract Factory Pattern and Singleton Patternjin/3132/lectures/dp-08.pdf · 2011-07-14 · The Abstract Factory Pattern and Singleton Pattern CSCI 3132 Summer 2011 1

The  Abstract  Factory  

PizzaIngredientFactory createDough() createSauce()

NYPizzaIngredientFactory ChicagoPizzaIngredientFactory

13

Page 14: The Abstract Factory Pattern and Singleton Patternjin/3132/lectures/dp-08.pdf · 2011-07-14 · The Abstract Factory Pattern and Singleton Pattern CSCI 3132 Summer 2011 1

            More  Ingredience    •  We  want  to  list  the  exact  list  of  ingredients  for  each  concrete  

pizza.  For  example  :  

– Chicago  Cheese  Pizza  :  Plum  tomato  Sauce,  Mozzarella,  Parmesan,  Oregano;  

– New  York  Cheese  Pizza  :  Marinara  Sauce,  Reggiano,  Garlic.  •  Each  “style”  uses  a  different  set  of  ingredients,    •  We  could  change  implement  Pizza  as  in:  public class Pizza { Dough dough; Sauce sauce; Veggies veggies[]; Cheese cheese; Pepperoni pepperoni; Clams clam; . . . }  

14

Page 15: The Abstract Factory Pattern and Singleton Patternjin/3132/lectures/dp-08.pdf · 2011-07-14 · The Abstract Factory Pattern and Singleton Pattern CSCI 3132 Summer 2011 1

•  and  the  constructor  naturally  becomes  something  like  :  

public Pizza(Dough d, Sauce s, Cheese c, Veggies v, Pepperoni p, Clams c) { dough = d; sauce = s; veggies = v; cheese = c; pepperoni = p; clam = c; }

15

Page 16: The Abstract Factory Pattern and Singleton Patternjin/3132/lectures/dp-08.pdf · 2011-07-14 · The Abstract Factory Pattern and Singleton Pattern CSCI 3132 Summer 2011 1

•  but  then:  public class NYPizzaStore extends PizzaStore {

Pizza createPizza(String item) {

if (item.equals("cheese")) { return new NYStyleCheesePizza(new ThinCrustDough(), new Marinara(), new Reggiano(), null, null ); } else if (item.equals("veggie")) { return new NYStyleVeggiaPizza(new ThinCrustDough(),

new Marinara(), new Reggiano(), mew Garlic() , null);

}

}

This will cause a lot of maintenance headaches! Imagine what happens when we create a new pizza!

16

Page 17: The Abstract Factory Pattern and Singleton Patternjin/3132/lectures/dp-08.pdf · 2011-07-14 · The Abstract Factory Pattern and Singleton Pattern CSCI 3132 Summer 2011 1

•  We  know  that  we  have  a  certain  set  of  ingredients  that  are  used  for  New  York..yet  we  have  to  keep  repea?ng  that  set  with  each  constructor.    Can  we  define  this  unique  set  just  once?  

•  A`er  all  we  are  crea?ng  concrete  instances  of  dough,  ingredients  etc.  :  

–  let’s  use  the  factory  of  ingredients!  public interface PizzaIngredientFactory {

public Dough createDough(); public Sauce createSauce(); public Cheese createCheese(); public Veggies[] createVeggies(); public Pepperoni createPepperoni(); public Clams createClam(); }

17

Page 18: The Abstract Factory Pattern and Singleton Patternjin/3132/lectures/dp-08.pdf · 2011-07-14 · The Abstract Factory Pattern and Singleton Pattern CSCI 3132 Summer 2011 1

•  We  then  “program  to  the  interface”  by  implemen?ng  different  concrete  ingredients  factories.  For  example  here  are  the  ingredients  used  in  New  York  pizza  style:  

public class NYPizzaIngredientFactory : PizzaIngredientFactory { public Dough createDough() { return new ThinCrustDough(); } public Sauce createSauce() { return new MarinaraSauce(); } public Cheese createCheese() { return new ReggianoCheese(); } //... }

18

Page 19: The Abstract Factory Pattern and Singleton Patternjin/3132/lectures/dp-08.pdf · 2011-07-14 · The Abstract Factory Pattern and Singleton Pattern CSCI 3132 Summer 2011 1

•  Our  Pizza  class  will  remain  an  abstract  class:  public abstract class Pizza { protected string name; protected Dough dough;

protected Sauce sauce; protected ArrayList toppings = new ArrayList();

abstract void Prepare(); //now abstract public virtual string Bake() { Console.WriteLine("Bake for 25 minutes at 350 \n“); } public virtual string Cut() { Console.WriteLine("Cutting the pizza into diagonal slices \n“); } // ... }  

19

Page 20: The Abstract Factory Pattern and Singleton Patternjin/3132/lectures/dp-08.pdf · 2011-07-14 · The Abstract Factory Pattern and Singleton Pattern CSCI 3132 Summer 2011 1

•  and  our  concrete  Pizza  simply  bevome:  public class CheesePizza : Pizza {

PizzaIngredientFactory ingredientFactory; public CheesePizza(PizzaIngredientFactory ingredientFactory) {

this.ingredientFactory = ingredientFactory;

}

void prepare() {

dough = ingredientFactory.createDough(); sauce = ingredientFactory.createSauce(); cheese = ingredientFactory.createCheese(); }

}

the  crea?on  of  the  ingredients  is  delegated  to  a  factory.  

20

Page 21: The Abstract Factory Pattern and Singleton Patternjin/3132/lectures/dp-08.pdf · 2011-07-14 · The Abstract Factory Pattern and Singleton Pattern CSCI 3132 Summer 2011 1

•  finally  we  must  have  our  concrete  Pizza  store  e.g.    

public class NYPizzaStore : PizzaStore {

protected Pizza createPizza(String item) {

Pizza pizza = null;

PizzaIngredientFactory ingredientFactory = new NYPizzaIngredientFactory(); if (item.equals("cheese")) {

pizza = new CheesePizza(ingredientFactory); } else if (item.equals("veggie")) {

pizza = new VeggiePizza(ingredientFactory); } else if (item.equals("clam")) {

pizza = new ClamPizza(ingredientFactory); } else if (item.equals("pepperoni")) {

pizza = new PepperoniPizza(ingredientFactory); }

return pizza;

}

} 21

Page 22: The Abstract Factory Pattern and Singleton Patternjin/3132/lectures/dp-08.pdf · 2011-07-14 · The Abstract Factory Pattern and Singleton Pattern CSCI 3132 Summer 2011 1

Abstract  Factory  Pa0ern  <<interface>>

AbstractFactory createProductA() createProductB() <<interface>>

AbstractProductA <<interface>>

AbstractProductB

Client

ConcreteFactory1 createProductA() createProductB()

ConcreteFactory2 createProductA() createProductB()

ConcreteProductA1

ConcreteProductA2

ConcreteProductB1

ConcreteProductB2

22

Page 23: The Abstract Factory Pattern and Singleton Patternjin/3132/lectures/dp-08.pdf · 2011-07-14 · The Abstract Factory Pattern and Singleton Pattern CSCI 3132 Summer 2011 1

Abstract  Factory  Summary  •  The  Abstract  Factory  Pa0ern  “provides  an  interface  for  crea?ng  

families  of  related  or  dependent  objects  without  specifying  their  concrete  classes”.  

•  Factory  Method:  

– Uses  inheritance    to  create  a  Concrete  Product  – Sub  classes  decide  which  Concrete  Product  to  use  

•  Abstract  Factory:  – Uses  composi?on  to  create  objects  

– The  objects  created  were  a  part  of  a  family  of  objects.  For  example,  NY  region  had  a  specific  set  of  ingredients.  

– An  abstract  factory  actually  contains  one  or  more  Factory  Methods!  

23

Page 24: The Abstract Factory Pattern and Singleton Patternjin/3132/lectures/dp-08.pdf · 2011-07-14 · The Abstract Factory Pattern and Singleton Pattern CSCI 3132 Summer 2011 1

The  Abstract  Factory  

•  By  making  a  creator  class  with  several  create…  methods,  we  restrict  the  product  combina?ons  the  client  can  create  

•  The  methods  in  the  Abstract  Factory  are  product-­‐type  dependent,  so  if  we  add  another  product,  we  need  to  change  the  interface  of  the  base  class  

•  This  is  a  price  we  must  pay  for  binding  (formally)  non-­‐related  types  together  

24

Page 25: The Abstract Factory Pattern and Singleton Patternjin/3132/lectures/dp-08.pdf · 2011-07-14 · The Abstract Factory Pattern and Singleton Pattern CSCI 3132 Summer 2011 1

Crea?ng  a  Single  Instance  of  a  Class  

•  In  some  cases  it  maybe  necessary  to  create  just  one  instance  of  a  class.  

•  This  maybe  necessary  because:  – More  than  one  instance  will  result  in  incorrect  program  behavior  

– More  than  one  instance  will  result  in  the  overuse  of  resources  

– More  than  one  instance  will  result  in  inconsistent  results  

– There  is  a  need  for  a  global  point  of  access  •  How  would  you  ensure  that  just  one  instance  of  a  class  is  created?  

25

Page 26: The Abstract Factory Pattern and Singleton Patternjin/3132/lectures/dp-08.pdf · 2011-07-14 · The Abstract Factory Pattern and Singleton Pattern CSCI 3132 Summer 2011 1

Singleton  Pa0ern  Overview  

•  In  some  cases  there  should  be  at  most  one  instance  of  a  class.      

•  This  one  instance  must  be  accessible  by  all  “clients”,  e.g.  a  printer  spooler.  

•  This  usually  occurs  when  a  global  resource  has  to  be  shared.  

•  The  singleton  pa0ern  ensures  that  a  class  has  only  one  instance  and  provides  only  one  point  of  entry.  

26

Page 27: The Abstract Factory Pattern and Singleton Patternjin/3132/lectures/dp-08.pdf · 2011-07-14 · The Abstract Factory Pattern and Singleton Pattern CSCI 3132 Summer 2011 1

   Implemen?ng  the  Singleton  Pa0ern  

•  Implement  a  private  constructor  to  prevent  other  classes  from  declaring  more  than  one  instance.  

•  Implement  a  method  to  create  a  single  instance.    Make  this  method  sta?c.  

•  Create  a  lazy  instance  of  the  class  in  the  class.  •   Make  the  data  element  sta?c.  

27

Page 28: The Abstract Factory Pattern and Singleton Patternjin/3132/lectures/dp-08.pdf · 2011-07-14 · The Abstract Factory Pattern and Singleton Pattern CSCI 3132 Summer 2011 1

Thread  Example  

A A dual processor machine, with two threads calling the getInstance() method for the chocolate boiler

Thread  1   Thread  2  

public stat ChocolateBoiler!! getInstance()!

public stat ChocolateBoiler!! getInstance()!

if (uniqueInstance == null)!

if (uniqueInstance == null)!

uniqueInstance = ! new ChocolateBoiler()!

uniqueInstance = ! new ChocolateBoiler()!

return uniqueInstance;!

return uniqueInstance;! 28

Page 29: The Abstract Factory Pattern and Singleton Patternjin/3132/lectures/dp-08.pdf · 2011-07-14 · The Abstract Factory Pattern and Singleton Pattern CSCI 3132 Summer 2011 1

Problems  with  Mul?threading  

•  In  the  case  of  mul?threading  with  more  than  one  processor  the  getInstance()  method  could  be  called  at  more  or  less  the  same  ?me  resul?ng  in  to  more  than  one  instance  being  created.  

•  Possible  solu?ons:  – Synchronize  the  getInstance()  method  – Do  nothing  if  the  getInstance()  method  is  not  cri?cal  to  the  applica?on.  

– Move  to  an  eagerly  created  instance  rather  than  a  lazily  created  one.  

29

Page 30: The Abstract Factory Pattern and Singleton Patternjin/3132/lectures/dp-08.pdf · 2011-07-14 · The Abstract Factory Pattern and Singleton Pattern CSCI 3132 Summer 2011 1

Synchronizing  the  getInstance()  Method  

•  Code      public static synchronized Singleton getInstance() {…

}

•  Disadvantage  –  synchronizing  can  decrease  system  performance  by  a  factor  of  100.  

30

Page 31: The Abstract Factory Pattern and Singleton Patternjin/3132/lectures/dp-08.pdf · 2011-07-14 · The Abstract Factory Pattern and Singleton Pattern CSCI 3132 Summer 2011 1

Use  an  Eagerly  Created  Instance  Rather  than  a  Lazy  One  

•  Code:  //Data elements public static Singleton uniqueInstance = new

Singleton()

private Singleton() {}

public static Singleton getInstance() { return uniqueInstance }

•  Disadvantage  –  Memory  may  be  allocated     and  not  used.  

31

Page 32: The Abstract Factory Pattern and Singleton Patternjin/3132/lectures/dp-08.pdf · 2011-07-14 · The Abstract Factory Pattern and Singleton Pattern CSCI 3132 Summer 2011 1

Singleton  Pa0ern  Summary  

•  The  singleton  pa0ern  ensures  that  there  is  just  one  instance  of  a  class.  

•  The  singleton  pa0ern  provides  a  global  access  point.  

•  The  pa0ern  is  implemented  by  using  a  private  constructor  and  a  sta?c  method  combined  with  a  sta?c  variable.  

•  Possible  problems  with  mul?threading.  •  Versions  of  Java  earlier  that  1.2  automa?cally  clear  singletons  that  are  not  being  accessed  as  part  of  garbage  collec?on.  

32