diff --git a/README.md b/README.md index 9e0034c..c243599 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,30 @@ -# DesignPatternsJava9 -This repo consists Gang of Four Design patterns code on Java 9. Each branch in the repository has code of 1 design pattern. Switch repository to try out different design patterns. +# What is Abstract Factory Design Pattern +Abstract factory is also called as factory of factories. Abstract Factory patterns work around a super-factory which creates other factories. In Abstract Factory pattern an interface is responsible for creating a factory of related objects without explicitly specifying their classes. Each generated factory can give the objects as per the Factory pattern. + +## Diagram +![Diagram](https://github.com/premaseem/DesignPatternsJava9/blob/abstract-factory/diagrams/3_5%20Abstract%20Factory%20Design%20Pattern%20-%20class%20diagram.jpeg "Diagram") + +![Diagram](https://github.com/premaseem/DesignPatternsJava9/blob/abstract-factory/diagrams/3_5%20Abstract%20Factory%20design%20pattern%20-%20sequence%20diagrams.png "Diagram") + +### When to use Abstract Factory Design Pattern +When application needs a level of indirection that abstracts the creation of families of related or dependent objects without directly specifying their concrete classes. The "factory" object has the responsibility for providing creation services for the entire platform family. + +### Learn Design Patterns with Java by Aseem Jain +This repository contains working project code used in video Course by Packt Publication with title "Learn Design Patterns with Java " authored by "Aseem Jain". + +### Course link: +https://www.packtpub.com/application-development/learn-design-patterns-java-9-video + +### ![ http://in.linkedin.com/in/premaseem](https://github.com/premaseem/DesignPatternsJava9/blob/master/linkedin.png "http://in.linkedin.com/in/premaseem") Profile: http://in.linkedin.com/in/premaseem + +### Authors blog on design patterns: +https://premaseem.wordpress.com/category/computers/design-patterns/ + +### Software Design pattern community face book page: +https://www.facebook.com/DesignPatternGuru/ + +### Note: +* This code base will work on Java 9 and above versions. +* `diagrams` folders carry UML diagrams. +* `pattern` folder has code of primary example. +* `patternBonus` folder has code of secondary or bonus example. diff --git a/diagrams/3_5 Abstract Factory Design Pattern - class diagram.jpeg b/diagrams/3_5 Abstract Factory Design Pattern - class diagram.jpeg new file mode 100644 index 0000000..bd32e53 Binary files /dev/null and b/diagrams/3_5 Abstract Factory Design Pattern - class diagram.jpeg differ diff --git a/diagrams/3_5 Abstract Factory design pattern - sequence diagrams.png b/diagrams/3_5 Abstract Factory design pattern - sequence diagrams.png new file mode 100644 index 0000000..d55e2c0 Binary files /dev/null and b/diagrams/3_5 Abstract Factory design pattern - sequence diagrams.png differ diff --git a/pattern/src/com/premaseem/AbstractIceCreamFactory.java b/pattern/src/com/premaseem/AbstractIceCreamFactory.java new file mode 100644 index 0000000..358fb6f --- /dev/null +++ b/pattern/src/com/premaseem/AbstractIceCreamFactory.java @@ -0,0 +1,15 @@ +package com.premaseem; + +import com.premaseem.icecreams.IceCream; +import com.premaseem.milkshake.MilkShake; + +/* +@author: Aseem Jain +@title: Design Patterns with Java 9 +@link: https://premaseem.wordpress.com/category/computers/design-patterns/ +*/ +public abstract class AbstractIceCreamFactory { + abstract IceCream createIceCream(String choice); + abstract MilkShake createMilkShake(String choice); + +} diff --git a/pattern/src/com/premaseem/AmulIceCreamFactory.java b/pattern/src/com/premaseem/AmulIceCreamFactory.java new file mode 100644 index 0000000..a1de13b --- /dev/null +++ b/pattern/src/com/premaseem/AmulIceCreamFactory.java @@ -0,0 +1,47 @@ +package com.premaseem; + +import com.premaseem.icecreams.ChocolateIceCream; +import com.premaseem.icecreams.IceCream; +import com.premaseem.icecreams.StrawberryIceCream; +import com.premaseem.milkshake.ChocolateMilkShake; +import com.premaseem.milkshake.MilkShake; +import com.premaseem.milkshake.StrawberryMilkShake; + +/* +@author: Aseem Jain +@title: Design Patterns with Java 9 +@link: https://premaseem.wordpress.com/category/computers/design-patterns/ +*/ + +/** + * This factory creates all daily products of Amul Brand + */ +public class AmulIceCreamFactory extends AbstractIceCreamFactory{ + + @Override + public IceCream createIceCream(String iceCreamChoice){ + IceCream iceCream = null; + + if (iceCreamChoice.equalsIgnoreCase("Strawberry")){ + iceCream = new StrawberryIceCream("Amul",2,120); + + }else if (iceCreamChoice.equalsIgnoreCase("Chocolate")){ + iceCream = new ChocolateIceCream("Amul",2,250); + } + + return iceCream; + } + + @Override + MilkShake createMilkShake (String choice) { + MilkShake milkShake = null; + + if (choice.equalsIgnoreCase("Strawberry")){ + milkShake = new StrawberryMilkShake("Amul",2); + + }else if (choice.equalsIgnoreCase("Chocolate")){ + milkShake = new ChocolateMilkShake("Amul",2); + } + return milkShake; + } +} diff --git a/pattern/src/com/premaseem/Client.java b/pattern/src/com/premaseem/Client.java index 15f05df..d2f0405 100644 --- a/pattern/src/com/premaseem/Client.java +++ b/pattern/src/com/premaseem/Client.java @@ -4,10 +4,83 @@ @author: Aseem Jain @title: Design Patterns with Java 9 @link: https://premaseem.wordpress.com/category/computers/design-patterns/ -@copyright: 2018 Packt Publication */ + +import com.premaseem.icecreams.IceCream; +import com.premaseem.milkshake.MilkShake; + +import java.util.Scanner; + public class Client { public static void main (String[] args) { - System.out.println("Singleton cook example "); + Scanner scan = new Scanner(System.in); + System.out.println("Ice cream Abstract factory example "); + + + System.out.println("What you would like to order ... "); + System.out.println("Icecream"); + System.out.println("Milkshake"); + String choice = scan.next(); + + System.out.println("Please enter your ice cream flavor ... "); + System.out.println("Strawberry"); + System.out.println("Chocolate"); + String flavor = scan.next(); + + System.out.println("Please enter the Brand of Ice cream ... "); + System.out.println("Dairy Queen"); + System.out.println("Amul"); + String brand = scan.next(); + + AbstractIceCreamFactory factory = FactoryCreator.getFactory(brand); + + // Virtual constructor ( takes care of configuration ) + if ( choice.equalsIgnoreCase("icecream")) { + IceCream iceCream = factory.createIceCream(flavor); + System.out.println(iceCream); + }else { + MilkShake milkShake = factory.createMilkShake(flavor); + System.out.println(milkShake); + } + + // Family of similar products with different brands. ( Tight couple) +// DairyQueenStrawberryIceCream dairyQueenStrawberryIceCream =null; +// DairyQueenChocolateIceCream dairyQueenChocolateIceCream = null; +// AmulStrawberryIceCream amulStrawberryIceCream =null; +// AmulChocolateIceCream amulchocolateIceCream = null; + +// // Sphegati code with if else ladder +// if (iceCreamBrand.equalsIgnoreCase("Amul") +// && iceCreamChoice.equalsIgnoreCase("Strawberry")){ +// amulStrawberryIceCream = new AmulStrawberryIceCream(); +// +// }else if (iceCreamBrand.equalsIgnoreCase("Amul") && +// iceCreamChoice.equalsIgnoreCase("Chocolate")){ +// amulchocolateIceCream = new AmulChocolateIceCream(); +// +// }else if (iceCreamBrand.equalsIgnoreCase("Dairy Queen") +// && iceCreamChoice.equalsIgnoreCase("Strawberry")){ +// dairyQueenStrawberryIceCream = new DairyQueenStrawberryIceCream(); +// +// }else if (iceCreamBrand.equalsIgnoreCase("Dairy Queen") && +// iceCreamChoice.equalsIgnoreCase("Chocolate")){ +// dairyQueenChocolateIceCream = new DairyQueenChocolateIceCream(); +// } +// +// // Ice cream of your choice is : +// System.out.print("Ice cream of your choice is "); +// if (amulStrawberryIceCream != null){ +// System.out.println(amulStrawberryIceCream); +// } +// if (amulchocolateIceCream != null){ +// System.out.println(amulchocolateIceCream); +// } +// if (dairyQueenStrawberryIceCream != null){ +// System.out.println(dairyQueenStrawberryIceCream); +// } +// if (dairyQueenChocolateIceCream != null){ +// System.out.println(dairyQueenChocolateIceCream); +// } + } } diff --git a/pattern/src/com/premaseem/DairyQueenCreamFactory.java b/pattern/src/com/premaseem/DairyQueenCreamFactory.java new file mode 100644 index 0000000..b62ec3d --- /dev/null +++ b/pattern/src/com/premaseem/DairyQueenCreamFactory.java @@ -0,0 +1,47 @@ +package com.premaseem; + +import com.premaseem.icecreams.ChocolateIceCream; +import com.premaseem.icecreams.IceCream; +import com.premaseem.icecreams.StrawberryIceCream; +import com.premaseem.milkshake.ChocolateMilkShake; +import com.premaseem.milkshake.MilkShake; +import com.premaseem.milkshake.StrawberryMilkShake; + +/* +@author: Aseem Jain +@title: Design Patterns with Java 9 +@link: https://premaseem.wordpress.com/category/computers/design-patterns/ +*/ + +/** + * This factory creates all daily products of Dairy Queen Brand + */ +public class DairyQueenCreamFactory extends AbstractIceCreamFactory{ + + @Override + public IceCream createIceCream(String iceCreamChoice){ + IceCream iceCream = null; + + if (iceCreamChoice.equalsIgnoreCase("Strawberry")){ + iceCream = new StrawberryIceCream("Dairy Queen",2,120); + + }else if (iceCreamChoice.equalsIgnoreCase("Chocolate")){ + iceCream = new ChocolateIceCream("Dairy Queen",2,250); + } + + return iceCream; + } + + @Override + MilkShake createMilkShake (String choice) { + MilkShake milkShake = null; + + if (choice.equalsIgnoreCase("Strawberry")){ + milkShake = new StrawberryMilkShake("Dairy Queen",2); + + }else if (choice.equalsIgnoreCase("Chocolate")){ + milkShake = new ChocolateMilkShake("Dairy Queen",2); + } + return milkShake; + } +} diff --git a/pattern/src/com/premaseem/FactoryCreator.java b/pattern/src/com/premaseem/FactoryCreator.java new file mode 100644 index 0000000..aef971a --- /dev/null +++ b/pattern/src/com/premaseem/FactoryCreator.java @@ -0,0 +1,16 @@ +package com.premaseem; + +/* +@author: Aseem Jain +@title: Design Patterns with Java 9 +@link: https://premaseem.wordpress.com/category/computers/design-patterns/ +*/ +public class FactoryCreator { + static AbstractIceCreamFactory getFactory (String brand) { + if (brand.equalsIgnoreCase("Amul")){ + return new AmulIceCreamFactory(); + }else { + return new DairyQueenCreamFactory(); + } + } +} diff --git a/pattern/src/com/premaseem/icecreams/ChocolateIceCream.java b/pattern/src/com/premaseem/icecreams/ChocolateIceCream.java new file mode 100644 index 0000000..69c2839 --- /dev/null +++ b/pattern/src/com/premaseem/icecreams/ChocolateIceCream.java @@ -0,0 +1,40 @@ +package com.premaseem.icecreams; + +/* +@author: Aseem Jain +@title: Design Patterns with Java 9 +@link: https://premaseem.wordpress.com/category/computers/design-patterns/ +*/ +public class ChocolateIceCream implements IceCream { + + public ChocolateIceCream (String brand,Integer cost, Integer calories){ + this.brand = brand; + this.cost =cost; + this.calories =calories; + } + + String brand = ""; + Integer cost = 0; + Integer calories = 0; + + + @Override + public Integer getCalories () { + return calories; + } + + @Override + public Integer getCost () { + return cost; + } + + @Override + public String getBrand () { + return brand; + } + + public String toString () { + return this.getClass().getSimpleName() + "of Brand " + brand + + " with Calories: " + getCalories() + " and cost: $" + getCost(); + } +} diff --git a/pattern/src/com/premaseem/icecreams/IceCream.java b/pattern/src/com/premaseem/icecreams/IceCream.java new file mode 100644 index 0000000..2f44423 --- /dev/null +++ b/pattern/src/com/premaseem/icecreams/IceCream.java @@ -0,0 +1,16 @@ +package com.premaseem.icecreams; + +/* +@author: Aseem Jain +@title: Design Patterns with Java 9 +@link: https://premaseem.wordpress.com/category/computers/design-patterns/ +*/ +public interface IceCream { + + Integer getCalories(); + Integer getCost(); + String getBrand(); + + + +} diff --git a/pattern/src/com/premaseem/icecreams/StrawberryIceCream.java b/pattern/src/com/premaseem/icecreams/StrawberryIceCream.java new file mode 100644 index 0000000..9d1461e --- /dev/null +++ b/pattern/src/com/premaseem/icecreams/StrawberryIceCream.java @@ -0,0 +1,40 @@ +package com.premaseem.icecreams; + +/* +@author: Aseem Jain +@title: Design Patterns with Java 9 +@link: https://premaseem.wordpress.com/category/computers/design-patterns/ +*/ +public class StrawberryIceCream implements IceCream { + + String brand; + Integer cost; + Integer calories; + + public StrawberryIceCream(String brand, Integer cost,Integer calories){ + this.brand=brand; + this.cost =cost; + this.calories =calories; + } + + public String toString () { + return this.getClass().getSimpleName() + "of Brand " + brand + + " with Calories: " + getCalories() + " and cost: $" + getCost(); + } + + @Override + public Integer getCalories () { + return calories; + } + + @Override + public Integer getCost () { + return cost; + } + + @Override + public String getBrand () { + return brand; + } + +} diff --git a/pattern/src/com/premaseem/milkshake/ChocolateMilkShake.java b/pattern/src/com/premaseem/milkshake/ChocolateMilkShake.java new file mode 100644 index 0000000..615f04a --- /dev/null +++ b/pattern/src/com/premaseem/milkshake/ChocolateMilkShake.java @@ -0,0 +1,30 @@ +package com.premaseem.milkshake; + +/* +@author: Aseem Jain +@title: Design Patterns with Java 9 +@link: https://premaseem.wordpress.com/category/computers/design-patterns/ +*/ +public class ChocolateMilkShake implements MilkShake{ + String brand; + Integer iceCubes; + + public ChocolateMilkShake (String brand, Integer iceCubes){ + this.brand = brand; + this.iceCubes = iceCubes; + } + @Override + public Integer getIceAmount () { + return this.iceCubes; + } + + @Override + public String getBrand () { + return this.brand; + } + + @Override + public String toString () { + return super.toString(); + } +} diff --git a/pattern/src/com/premaseem/milkshake/MilkShake.java b/pattern/src/com/premaseem/milkshake/MilkShake.java new file mode 100644 index 0000000..50fef37 --- /dev/null +++ b/pattern/src/com/premaseem/milkshake/MilkShake.java @@ -0,0 +1,11 @@ +package com.premaseem.milkshake; + +/* +@author: Aseem Jain +@title: Design Patterns with Java 9 +@link: https://premaseem.wordpress.com/category/computers/design-patterns/ +*/ +public interface MilkShake { + Integer getIceAmount(); + String getBrand(); +} diff --git a/pattern/src/com/premaseem/milkshake/StrawberryMilkShake.java b/pattern/src/com/premaseem/milkshake/StrawberryMilkShake.java new file mode 100644 index 0000000..08ed5db --- /dev/null +++ b/pattern/src/com/premaseem/milkshake/StrawberryMilkShake.java @@ -0,0 +1,25 @@ +package com.premaseem.milkshake; + +/* +@author: Aseem Jain +@title: Design Patterns with Java 9 +@link: https://premaseem.wordpress.com/category/computers/design-patterns/ +*/ +public class StrawberryMilkShake implements MilkShake{ + String brand; + Integer iceCubes; + + public StrawberryMilkShake(String brand, Integer iceCubes){ + this.brand = brand; + this.iceCubes = iceCubes; + } + @Override + public Integer getIceAmount () { + return this.iceCubes; + } + + @Override + public String getBrand () { + return this.brand; + } +} diff --git a/patternBonus/src/com/premaseem/Client.java b/patternBonus/src/com/premaseem/Client.java deleted file mode 100644 index 15f05df..0000000 --- a/patternBonus/src/com/premaseem/Client.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.premaseem; - -/* -@author: Aseem Jain -@title: Design Patterns with Java 9 -@link: https://premaseem.wordpress.com/category/computers/design-patterns/ -@copyright: 2018 Packt Publication -*/ -public class Client { - public static void main (String[] args) { - System.out.println("Singleton cook example "); - } -} diff --git a/patternBonus/src/com/premaseem/abstractFactory/AbstracePizzaFactory.java b/patternBonus/src/com/premaseem/abstractFactory/AbstracePizzaFactory.java new file mode 100644 index 0000000..4b4e495 --- /dev/null +++ b/patternBonus/src/com/premaseem/abstractFactory/AbstracePizzaFactory.java @@ -0,0 +1,40 @@ +package com.premaseem.abstractFactory; + +// Example of Abstract Factory Pattern +public abstract class AbstracePizzaFactory { + + // Example of Factory method pattern + public abstract Pizza createPizzaBase(String PizzaType); + public Pizza getPizzaBase(String pizzaType) { + return createPizzaBase(pizzaType); + } +} + +class JainPizzaFactory extends AbstracePizzaFactory{ + @Override + public Pizza createPizzaBase(String pizzaType) { + // Example of Simple Factory pattern + Pizza pizza = null; + if(pizzaType.equalsIgnoreCase("veg")){ + pizza = new JainVegPizza(); + }else + if(pizzaType.equalsIgnoreCase("corn")){ + pizza = new JainCornPizza(); + } + return pizza; + } +} + +class GeneralPizzaFactory extends AbstracePizzaFactory{ + @Override + public Pizza createPizzaBase(String pizzaType) { + Pizza pizza = null; + if(pizzaType.equalsIgnoreCase("veg")){ + pizza = new VegPizza(); + }else + if(pizzaType.equalsIgnoreCase("corn")){ + pizza = new CornPizza(); + } + return pizza; + } +} \ No newline at end of file diff --git a/patternBonus/src/com/premaseem/abstractFactory/ClientForPizzaFactory.java b/patternBonus/src/com/premaseem/abstractFactory/ClientForPizzaFactory.java new file mode 100644 index 0000000..a5db42c --- /dev/null +++ b/patternBonus/src/com/premaseem/abstractFactory/ClientForPizzaFactory.java @@ -0,0 +1,38 @@ +package com.premaseem.abstractFactory; + +import java.util.Scanner; + +public class ClientForPizzaFactory { + + public static void main(String[] args) { + Scanner scan = new Scanner(System.in); + int repeatRunFlag = 1; + while (repeatRunFlag == 1) { + + System.out.println("This is the Client Main Abstract Factory Pattern containing all "); + + System.out.println("What kind of Pizza would you like to have Jain Pizza or General Pizza ? "); + System.out.println("Press Jain / general "); + String pizzafactory = scan.next(); + + System.out.println("Enter veg for veg pizza "); + System.out.println("Enter corn for corn pizza "); + String pizzaType = scan.next(); + PizzaStore pizzaStore = new PizzaStore(); + Pizza pizza = pizzaStore.orderPizza(pizzafactory, pizzaType); + + // PizzaBase pizza = PizzaFactory.getPizza(pizzaType); + + System.out.println("Your final order is"); + pizza.getDescription(); + System.out.println("Toal cost of order is " + pizza.getCost()); + System.out.println("\n $$$$$$$$$$$$$$$$$$$$ Thanks by Prem Aseem $$$$$$$$$$$$$$$$$$$$$$ \n "); + System.out.println("Do you want to Re-run this program - Press 1 for yes and 0 or other digits to EXIT "); + try { + repeatRunFlag = scan.nextInt(); + } catch (Exception e) { + repeatRunFlag = 0; + } + } + } +} diff --git a/patternBonus/src/com/premaseem/abstractFactory/Pizza.java b/patternBonus/src/com/premaseem/abstractFactory/Pizza.java new file mode 100644 index 0000000..9a72c0e --- /dev/null +++ b/patternBonus/src/com/premaseem/abstractFactory/Pizza.java @@ -0,0 +1,63 @@ +package com.premaseem.abstractFactory; + +public interface Pizza { + void getDescription(); + + double getCost(); +} + +class VegPizza implements Pizza { + @Override + public void getDescription() { + // TODO Auto-generated method stub + System.out.println(" Veg Pizza from general Factory"); + } + + @Override + public double getCost() { + // TODO Auto-generated method stub + return 10.1; + } +} + +class JainVegPizza implements Pizza { + @Override + public void getDescription() { + // TODO Auto-generated method stub + System.out.println(" Veg Pizza from Jain Factory"); + } + + @Override + public double getCost() { + // TODO Auto-generated method stub + return 11.1; + } +} + +class CornPizza implements Pizza { + @Override + public void getDescription() { + // TODO Auto-generated method stub + System.out.println(" Corn Pizza from general Factory"); + } + + @Override + public double getCost() { + // TODO Auto-generated method stub + return 20.1; + } +} + +class JainCornPizza implements Pizza { + @Override + public void getDescription() { + // TODO Auto-generated method stub + System.out.println(" Corn Pizza from Jain Factory"); + } + + @Override + public double getCost() { + // TODO Auto-generated method stub + return 22.1; + } +} diff --git a/patternBonus/src/com/premaseem/abstractFactory/PizzaStore.java b/patternBonus/src/com/premaseem/abstractFactory/PizzaStore.java new file mode 100644 index 0000000..6c8b71a --- /dev/null +++ b/patternBonus/src/com/premaseem/abstractFactory/PizzaStore.java @@ -0,0 +1,27 @@ +package com.premaseem.abstractFactory; + +public class PizzaStore { + + public Pizza orderPizza(String pizzafactory, String pizzaType) { + AbstracePizzaFactory pizzaFactory = getPizzaFactory(pizzafactory); + Pizza pizza = pizzaFactory.getPizzaBase(pizzaType); + bakePizza(); + return pizza; + } + + private AbstracePizzaFactory getPizzaFactory(String pizzafactory) { + if (pizzafactory.equalsIgnoreCase("Jain")) { + return new JainPizzaFactory(); + } else if (pizzafactory.equalsIgnoreCase("General")) { + return new GeneralPizzaFactory(); + } + + return new GeneralPizzaFactory(); + } + + + private void bakePizza() { + // TODO Auto-generated method stub + + } +}