Design Pattern --- (4) Factory method Pattern , (5) Abstract Factory Pattern === ## Under what circumstances will the factory method pattern be used? * A class cannot anticipate the type of objects it needs to create beforehand. For example: I have a suepr-class Animal and a ton of sub-classes like dog,cat,duck,etc. So I want to create an animal object but I don't know which sub-classes to be instantiated before the run time. In other words,I am able to dynamically select the type at the run time. * You want to localize the logic to instantiate a complex object. For example: EU and NA both have the cheese pizza,yet they taste are different,the relation diagram is : ![Pizza](https://imgur.com/1HxuZag.jpg "berforepizza" =400x500) But I can improve the complex relationships to make them more flexible: ![Pizza](https://imgur.com/Ibubkkq.jpg "afterpizza" =400x500) ## How does they implement in code? As per above situation,suppose I have the Pizza interface ,which has two subclass,cheese pizza and seafood pizza.In addition,there are two pizza store selling them but the taste is different. ```java abstract class PizzaStore { public abstract Pizza create(String taste); public Pizza order(String taste) { //create Pizza pizza = create(taste); //do something pizza.prepare(); pizza.cook(); return pizza; } } class NAPizzaStore extends PizzaStore { public Pizza create(String taste) { if(taste.equals("cheese")) return new NACheesePizza(); else if(taste.equals("seafood")) return new NASeafoodPizza(); return null; } } class EUPizzaStore extends PizzaStore { public Pizza create(String taste) { if(taste.equals("cheese")) return new EUCheesePizza(); else if(taste.equals("seafood")) return new EUSeafoodPizza(); return null; } } Interface Pizza { void prepare(); Pizza cook(); } public class client { public static void main(String[] arg ) { NYPizzaStore NYPS = new NYPizzaStore(); NYPS.order("cheese"); NYPS.order("seafood"); EUPizzaStore NYPS = new EUPizzaStore(); EUPS.order("cheese"); EUPS.order("seafood"); } } ``` --- ## What is the relationship between the factory method pattern and the abstract factory pattern ? The abstract factory pattern actually is a set of the factory methods,so an abstract factory makes use of multiple factory methods. ## Under what circumstances will the abstract factory pattern be used? An output of a factory depends on several factories. For example: Creating a pizza has to add a lot of ingredients like dough,sauce,etc,and each ingredients need a factory to output. Here is a code without using abstract factory to complete. ↓↓↓ ```java= class NAPizzaStore extends PizzaStore { NADoughFactory DF; NASauceFactory SF; NACheeseFactory CF; NAClamFactory CLF; public Pizza create(String taste) { if(taste.equals("cheese")) return new NACheesePizza(DF,SF,CF); else if(taste.equals("seafood")) return new NASeafoodPizza(DF,SF,CLF); return null; } } class NACheesePizza extends Pizza { NADoughFactory DF; NASauceFactory SF; NACheeseFactory CF; public NACheesePizza(NADoughFactory DF,NASauceFactory SF,NACheeseFactory CF) { this.DF =DF; this.SF =SF; this.CF =CF; } public void prepare() { dough = DF.create(); sauce = SF.create(); cheese = CF.create(); } } class EUPizzaStore extends PizzaStore { EUDoughFactory DF; EUSauceFactory SF; EUCheeseFactory CF; EUClamFactory CLF; public Pizza create(String taste) { if(taste.equals("cheese")) return new EUCheesePizza(DF,SF,CF); else if(taste.equals("seafood")) return new EUSeafoodPizza(DF,SF,CLF); return null; } } ``` Obviously,this code is almost unmaintainable,so the abstract factory will come into play. ## How does they implement in code? The concept is that I build a large abstract factory to manage the above-mentionted several ingredients factories. ```java= abstract class IngredientsFactory { public abstract Dough createDough(); public abstract Sauce createSauce(); public abstract Cheese createCheese(); public abstract Clam createClam(); } class NAIngredientsFactory extends IngredientsFactory { public Dough createDough() return new NADough(); public Sauce createSauce() return new NASauce(); public Cheese createCheese() return new NACheese; public Clam createClam() return new NAClam(); } class NAPizzaStore extends PizzaStore { NAIngredientsFactory NAIF = new NAIngredientsFactory(); public Pizza create(String taste) { if(taste.equals("cheese")) return new NACheesePizza(NAIF); else if(taste.equals("seafood")) return new NASeafoodPizza(NAIF); return null; } } class NACheesePizza extends Pizza { NAIngredientsFactory NAIF; public CheesePizza(NAIngredientsFactory NAIF) { this.NAIF = NAIF; } public void prepare() { dough = NAIF.createDough(); sauce = NAIF.createSauce(); cheese = NAIF.createCheese(); } } class EUIngredientsFactory extends IngredientsFactory { public Dough createDough() return new EUDough(); public Sauce createSauce() return new EUSauce(); public Cheese createCheese() return new EUCheese; public Clam createClam() return new EUClam(); } class EUPizzaStore extends PizzaStore { EUIngredientsFactory EUIF = new EUIngredientsFactory(); public Pizza create(String taste) { if(taste.equals("cheese")) return new CheesePizza(EUIF); else if(taste.equals("seafood")) return new SeafoodPizza(EUIF); return null; } } class EUCheesePizza extends Pizza { EUIngredientsFactory EUIF; public EUCheesePizza(EUIngredientsFactory EUIF) { this.EUIF = EUIF; } public void prepare() { dough = EUIF.createDough(); sauce = EUIF.createSauce(); cheese = EUIF.createCheese(); } } public class client { NAPizzaStore NAPS = new NAPizzaStore(); Pizza cheesepizza = NAPS.order("cheese"); Pizza seafoodpizza = NAPS.order("seafood"); EUPizzaStore EUPS = new EUPizzaStore(); Pizza cheesspizza = EUPS.order("cheese"); Pizza seafoodpizza = EUPS.order("seafood"); } ``` ## Conclusion The factory method and abstract factory both have the same keyword "defer".The former defers the instantiation from the super-class to the sub-classes and the latter defers the implementation of a set of factories to the sub-classes. ## Reference * Chris https://www.youtube.com/watch?v=EcFVTgRHJLM&t=1s https://www.youtube.com/watch?v=v-GiuMmsXj4 https://blog.techbridge.cc/2017/05/22/factory-method-and-abstract-factory/ ###### tags: `Design Pattern` `Java` `教學`