CSE316 : FUNDAMENTALS OF Lecture 14a : Intro to : Creational Design Patterns Topics

■ Intro to Design Patterns – Creational – Structural – Behavioral ■ ■ Singleton ■ Prototype ■

CSE316 : Fund of SW Development - Tony Mione, SUNY Korea - 2019 2 Intro to Design Patterns

■ Design patterns – are template solutions to common programming problems – Help us follow OO principles ■ There are several ‘categories’ of design patterns – Creational – These patterns help build objects in some way – Structural – Help assemble larger structures using various composition and aggregation techniques – Behavioral – These patterns are concerned with algorithms, assignment of responsibilities, and interactions between objects

CSE316 : Fund of SW Development - Tony Mione, SUNY Korea - 2019 3 Creational Patterns

■ Creational Patterns include: – Builder – Singleton – Prototype – Factory Method Pattern – Abstract Factory Pattern

CSE316 : Fund of SW Development - Tony Mione, SUNY Korea - 2019 4 Builder Pattern

■ Why Builder? – To build an object composed of other objects – The pattern hides the creation of component objects from the main object – The pattern also hides the details of creating the object from the ‘client’ code.

CSE316 : Fund of SW Development - Tony Mione, SUNY Korea - 2019 5 Builder Pattern

■ Main parts of this pattern: – A Director – This oversees construction of the object – A Builder – An interface that provides methods that build the component objects – A Concrete Builder – This implements the Builder interface to build a specific type of object – A Product Interface – An interface used by product to allow creation of component objects

CSE316 : Fund of SW Development - Tony Mione, SUNY Korea - 2019 6 Builder Pattern

CSE316 : Fund of SW Development - Tony Mione, SUNY Korea - 2019 7 // This interface is for an abstract builder Builder Pattern - Example public interface PizzaBuilder { public void addSauce(); public void addCheese(); ■ Example code: Pizza Store with ‘Pizza Builders’ public void addTopings(); public Pizza getPizza(); } // This is a concrete builder for NY style pizza // This is the 'Director' from the Builder Pattern public class NYPizzaBuilder implements PizzaBuilder { public class PizzaStore { private Pizza pizza; private PizzaBuilder pizzaBuilder; public NYPizzaBuilder() { this.pizza = new Pizza(); public PizzaStore(PizzaBuilder pizzaBuilder) { } this.pizzaBuilder = pizzaBuilder; @Override } public void addSauce() { pizza.setSauce("Red"); public Pizza getPizza() { } return pizzaBuilder.getPizza(); @Override } public void addCheese() { pizza.setCheese("Mozzarella"); public void makePizza() { } this.pizzaBuilder.addSauce(); @Override this.pizzaBuilder.addCheese(); public void addTopings() { this.pizzaBuilder.addTopings(); pizza.setToppings("Pepperoni"); } } } @Override public Pizza getPizza() { return this.pizza; } }

CSE316 : Fund of SW Development - Tony Mione, SUNY Korea - 2019 8 Builder Pattern - Example // Concrete Product: Pizza public class Pizza implements PizzaPlan { private String sauce; private String cheese; public interface PizzaPlan { private String toppings; // This is an interface for a product (Pizza) @Override public void setSauce(String sauce); public void setSauce(String sauce) { public void setCheese(String cheese); this.sauce = sauce; public void setToppings(String toppings); } } public String getSauce() { return sauce; } @Override public void setCheese(String cheese) { this.cheese = cheese; } public String getCheese() { return cheese; } @Override public void setToppings(String toppings) { this.toppings = toppings; } public String getToppings() { return toppings; } public String toString() { return "Pizza with: " + sauce + " sauce, " + cheese + " cheese, and " + toppings + " toppings."; } } CSE316 : Fund of SW Development - Tony Mione, SUNY Korea - 2019 9 Builder Pattern - Example

// Finally – How to use all this //Another concrete builder… this one for Boston Style public class BostonPizzaBuilder implements PizzaBuilder { public class TestPizzaBuilder { Pizza pizza; public static void main(String[] args) { public BostonPizzaBuilder() { this.pizza = new Pizza(); PizzaBuilder nyPizza = new NYPizzaBuilder(); } PizzaStore pizzaStore = new PizzaStore(nyPizza); @Override pizzaStore.makePizza(); public void addSauce() { Pizza myPizza = pizzaStore.getPizza(); pizza.setSauce("White"); System.out.println("My Pizza: " + myPizza); } @Override PizzaBuilder bostonPizza = new BostonPizzaBuilder(); public void addCheese() { pizzaStore = new PizzaStore(bostonPizza); pizza.setCheese("Feta"); pizzaStore.makePizza(); } Pizza myOtherPizza = pizzaStore.getPizza(); @Override System.out.println("My other pizza: " + myOtherPizza); public void addTopings() { } pizza.setToppings("clam and mushroom"); } } @Override public Pizza getPizza() { return this.pizza; // Output from a test run } } My Pizza: Pizza with: Red sauce, Mozzarella cheese, and Pepperoni toppings. My other pizza: Pizza with: White sauce, Feta cheese, and clam and mushroom toppings.

CSE316 : Fund of SW Development - Tony Mione, SUNY Korea - 2019 10

■ This pattern: – Supports applications that need an object of which only 1 instance can be created – Useful anywhere there is a single resource to share ■ Example Uses: – Print Spooler – ThreadPool – Memory Manager – Deck of Cards

CSE316 : Fund of SW Development - Tony Mione, SUNY Korea - 2019 11 Singleton Pattern

■ Components: – The Singleton Class – A single class that enforces creation of only 1 instance ■ Private Constructor ■ A private variable holding the instance of the Singleton ■ public getInstance() method ■ The getInstance() method: 1. Checks if the instance has been created 2. If it has, return that instance (reference) 3. If not, use the Constructor to build the instance and then return the instance

CSE316 : Fund of SW Development - Tony Mione, SUNY Korea - 2019 12 Singleton Pattern

CSE316 : Fund of SW Development - Tony Mione, SUNY Korea - 2019 13 Singleton Pattern ■ Example Singleton Code – Counter

public class Singleton { public void increment() { count++; private int count; } static Singleton theInstance; public String toString() { return "Count: " + count; private Singleton() { } count = 0; } } public static Singleton getInstance() { if (theInstance == null) { theInstance = new Singleton(); } return theInstance; }

CSE316 : Fund of SW Development - Tony Mione, SUNY Korea - 2019 14 Singleton Pattern ■ Example Singleton Code – Counter public class UseSingleton { public static void main(String[] args) { // Output from a run: Singleton s1 = Singleton.getInstance(); Singleton s2 = Singleton.getInstance(); S1: Count: 3 S2: Count: 3 s1.increment(); s2.increment(); s1.increment();

System.out.println("S1: " + s1); System.out.println("S2: " + s2); } }

CSE316 : Fund of SW Development - Tony Mione, SUNY Korea - 2019 15

■ This pattern: – Allows ‘cloning’ or ‘copying’ an object to create a new object – Allows adding any subclass of a known superclass at runtime – Good when there are numerous classes that you only want to use if needed at runtime – Reduces need for creating subclasses – Useful when creating an object from scratch is expensive

CSE316 : Fund of SW Development - Tony Mione, SUNY Korea - 2019 16 Prototype Pattern

CSE316 : Fund of SW Development - Tony Mione, SUNY Korea - 2019 17 Prototype Pattern - Example

public class Shape implements Cloneable {

// This is the prototype (the PrototypeInterface is ‘Cloneable’) private int id; private String name; private static int lastId = 0;

public Shape() { id = ++lastId; name = "Unknown"; } public Shape(String name) { this.name = name; id = ++lastId; } public void setName (String name) { this.name = name; } public void setId(int id) { this.id = id; } public String getName() { return name; } public int getId() { return id; } }

CSE316 : Fund of SW Development - Tony Mione, SUNY Korea - 2019 18 Prototype Pattern - Example // This is a prototype class which extends the Prototype // Tests the prototype Shape and clonging public class Circle extends Shape { public class UseShape { private int radius; public static void main(String[] args) { public Circle() { Circle firstShape = new Circle(1); super("Circle"); Circle second = (Circle) firstShape.makeCopy(); radius = 1; Circle third = second; } public Circle(int radius) { System.out.println("1st shape: " + firstShape); super("Circle"); System.out.println("second: " + second); this.radius = radius; System.out.println("Circle is made"); System.out.println("C1: " + System.identityHashCode(firstShape)); } System.out.println("C2: " + System.identityHashCode(second)); public Shape makeCopy() { System.out.println("C3: " + System.identityHashCode(third)); Circle circleObject = null; System.out.println("Circle is being cloned"); } try { } circleObject = (Circle) super.clone(); // Following is output from a run } catch (CloneNotSupportedException e) { e.printStackTrace(); Circle is made } Circle is being cloned circleObject.radius = this.radius; 1st shape: I am: Circle, with id=1 and a radius of 1 circleObject.setName(this.getName()); second: I am: Circle, with id=1 and a radius of 1 circleObject.setId(this.getId()); C1: 905544614 return circleObject; C2: 2137589296 } C3: 2137589296 public String toString() { return "I am: " + getName() + ", with id=" + getId() + " and a radius of " + radius; } } CSE316 : Fund of SW Development - Tony Mione, SUNY Korea - 2019 19 Factory Method Pattern

■ Method that returns one of several classes that have a common parent class ■ Class is chosen at run-time

CSE316 : Fund of SW Development - Tony Mione, SUNY Korea - 2019 20 Factory Method Pattern

■ When to use? – Not known ahead of time what class(es) you need – All potential classes are in the same class hierarchy – Want to centralize class selection code – Want to encapsulate object creation

CSE316 : Fund of SW Development - Tony Mione, SUNY Korea - 2019 21 Factory Method Pattern

CSE316 : Fund of SW Development - Tony Mione, SUNY Korea - 2019 22 Factory Method Pattern - Example ■ Let’s build some random aircraft for an Air Traffic Controller game import java.lang.StringBuilder; public abstract class Aircraft { public class FighterJet extends Aircraft { private String airType; private String design; public FighterJet(String airType, String design, int maxSpeed, boolean vtol) { private int maxSpeed; Base class (abstract) setAirType(airType); private boolean vtol; setDesign(design); setMaxSpeed(maxSpeed); public abstract void fly(); setVtol(vtol); Child class } public String getAirType() { return airType; } @Override public String getDesign() { return design; } public void fly() { public int getMaxSpeed() { return maxSpeed; } System.out.println("Zoooom...."); public boolean getVtol() { return vtol; } } public void setAirType(String airType) { this.airType = airType; } } public void setDesign(String design) { this.design = design; } public void setMaxSpeed(int maxSpeed) { this.maxSpeed = maxSpeed; } public class Helicopter extends Aircraft { public void setVtol (boolean vtol) { this.vtol = vtol; } public Helicopter(String airType, String design, int maxSpeed, boolean vtol) { public String toString() { setAirType(airType); StringBuilder retString; setDesign(design); retString = new StringBuilder("This is a " + airType + " with a " + design + " setMaxSpeed(maxSpeed); design. It can travel at a max speed of " + maxSpeed + " MPH and "); setVtol(vtol); Child class if (vtol) { } retString.append("can do vertical take off or landaing"); @Override } else { public void fly() { retString.append("can not do vertical take off or landaing"); System.out.println("Thumpa thumpa thumpa thump...."); } } return retString.toString(); } } } CSE316 : Fund of SW Development - Tony Mione, SUNY Korea - 2019 23 Factory Method Pattern - Example

public class AircraftFactory { // Factory method takes // typeOfAircraft // 1 - FighterJet The ‘Factory’ // 2 Helicopter // 3 - JumboJet public static Aircraft getAircraft(int typeOfAircraft) { if (typeOfAircraft == 1) { return new FighterJet("Fighter Jet", "sleek", 750, false); } else if (typeOfAircraft == 2) { return new Helicopter("Helicopter", "rotor-like", 350, true); } else if (typeOfAircraft == 3) { return new JumboJet("JumboJet", "fat", 650, false); } else { return null; } } }

CSE316 : Fund of SW Development - Tony Mione, SUNY Korea - 2019 24 Factory Method Pattern

import java.util.Random; public class UseAircraftFactory { Test Main public static void main(String[] args) { Random r = new Random(); Aircraft a[] = new Aircraft[10]; for (int i = 0; i < a.length; i++) { int val = r.nextInt(3) + 1; a[i] = AircraftFactory.getAircraft(val); // mae range 1-3 } System.out.println("Aircraft:"); for (int i = 0; i < a.length; i++) { if (a[i] != null) { System.out.println("A[" + i + "]: " + a[i]); a[i].fly(); } else { System.out.println("A[" + i + "]: not created!"); } } } }

CSE316 : Fund of SW Development - Tony Mione, SUNY Korea - 2019 25 Factory Method Pattern

Aircraft: A[0]: This is a Helicopter with a rotor-like design. It can travel at a max speed of 350 MPH and can do vertical take off or landaing Thumpa thumpa thumpa thump.... A[1]: This is a JumboJet with a fat design. It can travel at a max speed of 650 MPH and can not do vertical take off or landaing Shhheeeeoahh.... A[2]: This is a Helicopter with a rotor-like design. It can travel at a max speed of 350 MPH and can do vertical take off or landaing Thumpa thumpa thumpa thump.... A[3]: This is a JumboJet with a fat design. It can travel at a max speed of 650 MPH and can not do vertical take off or landaing Shhheeeeoahh.... A[4]: This is a Fighter Jet with a sleek design. It can travel at a max speed of 750 MPH and can not do vertical take off or landaing Zoooom.... A[5]: This is a Helicopter with a rotor-like design. It can travel at a max speed of 350 MPH and can do vertical take off or landaing Thumpa thumpa thumpa thump.... A[6]: This is a Helicopter with a rotor-like design. It can travel at a max speed of 350 MPH and can do vertical take off or landaing Thumpa thumpa thumpa thump.... A[7]: This is a Helicopter with a rotor-like design. It can travel at a max speed of 350 MPH and can do vertical take off or landaing Thumpa thumpa thumpa thump.... A[8]: This is a JumboJet with a fat design. It can travel at a max speed of 650 MPH and can not do vertical take off or landaing Shhheeeeoahh.... A[9]: This is a Helicopter with a rotor-like design. It can travel at a max speed of 350 MPH and can do vertical take off or landaing Thumpa thumpa thumpa thump....

CSE316 : Fund of SW Development - Tony Mione, SUNY Korea - 2019 26 Abstract Factory Pattern

■ Like Factory Method Pattern but: – Everything is Encapsulated ■ Method that orders objects ■ Factories that build objects ■ The final objects – Final Object contains objects that use the – Factory Method is a single method whereas Abstract Factory is a class with a collection of Factory Methods – Factory Method creates one object but Abstract Factory creates a group of related or dependent objects

CSE316 : Fund of SW Development - Tony Mione, SUNY Korea - 2019 27 Abstract Factory Pattern

■ Uses: – Applications that need to use a group of compatible objects ■ Collection of UI components (button, text input, dropdowns, etc)

CSE316 : Fund of SW Development - Tony Mione, SUNY Korea - 2019 28 Abstract Factory Pattern

CSE316 : Fund of SW Development - Tony Mione, SUNY Korea - 2019 29 Abstract Factory Pattern - Example

■ Abstract Factory applied to building Aircraft objects

Building – a type of broker that will simplify the factory interface for the client.

CSE316 : Fund of SW Development - Tony Mione, SUNY Korea - 2019 30 Abstract Factory Pattern - Example

public class FighterBody implements ACBody { public interface ACBody { @Override public String body(); public String body() { } return "thin tube body"; } public String toString() { return "thin tube body"; } } public interface ACTires { public class FighterLiftSystem implements ACLiftSystem { public String roll(); public String lift() { } return "sleek swept back style"; } public String toString() { return "sleek swept back style"; } }

public class FighterTires implements ACTires { public interface ACLiftSystem { @Override public String lift(); public String roll() { return "whisper roll"; } } public String toString() { return "whisper roll"; } } CSE316 : Fund of SW Development - Tony Mione, SUNY Korea - 2019 31 Abstract Factory Pattern - Example public abstract class Aircraft { private String name; ACTires tires; ACLiftSystem liftSystem; ACBody body;

public String getName() { return name; } public void setName(String name) { this.name = name; }

abstract void makeAircraft(); public String toString() { String infoOnAircraft = "The " + name + " has " + liftSystem + ", " + body + ", and " + tires; return infoOnAircraft; } } public class Fighter extends Aircraft { AircraftFactory acFactory; Fighter(AircraftFactory acFactory) { this.acFactory = acFactory; } @Override void makeAircraft() { tires = acFactory.createTires(); liftSystem = acFactory.createLiftSystem(); body = acFactory.createBody(); } } CSE316 : Fund of SW Development - Tony Mione, SUNY Korea - 2019 32 Abstract Factory Pattern - Example public interface AircraftFactory { public ACTires createTires(); public ACLiftSystem createLiftSystem(); public ACBody createBody(); } public class FighterFactory implements AircraftFactory { @Override public ACTires createTires() { return new FighterTires(); } @Override public ACLiftSystem createLiftSystem() { return new FighterLiftSystem(); } @Override public ACBody createBody() { return new FighterBody(); } }

CSE316 : Fund of SW Development - Tony Mione, SUNY Korea - 2019 33 Abstract Factory Pattern - Example public abstract class AircraftBuilding {

protected abstract Aircraft makeAC(String type);

public Aircraft orderAC(String type) { Aircraft theAC = makeAC(type); theAC.makeAircraft(); return theAC; } } public class FinalAircraftBuilding extends AircraftBuilding { Aircraft theAircraft = null; @Override protected Aircraft makeAC(String type) { if (type.equals("H")) { AircraftFactory acFact = new HelicopterFactory(); theAircraft = new Helicopter(acFact); theAircraft.setName("Henry"); } else if (type.equals("F")) { AircraftFactory acFact = new FighterFactory(); theAircraft = new Fighter(acFact); theAircraft.setName("Frank"); } return theAircraft; } } CSE316 : Fund of SW Development - Tony Mione, SUNY Korea - 2019 34 Abstract Factory Pattern – Example Test Code and Output

Test Code public class testFactories {

public static void main(String[] args) { AircraftBuilding fab = new FinalAircraftBuilding(); Aircraft theHeli = fab.orderAC("H"); System.out.println(theHeli); Aircraft theFighter = fab.orderAC("F"); System.out.println(theFighter); } }

Output

The Henry has thump style rotary blades, fat body with cargo room, and clunky roll The Frank has sleek swept back style, thin tube body, and whisper roll

CSE316 : Fund of SW Development - Tony Mione, SUNY Korea - 2019 35 Summary

■ Design patterns fall into three major categories: Creational, Structural, and Behavioral ■ Creational patterns are used to build objects in different manners allowing decoupling of the application from what objects are created or how objects are created ■ The major creational patterns are: – Builder Pattern – Singleton – Prototype – Factory Method Pattern – Abstract Factory Pattern

CSE316 : Fund of SW Development - Tony Mione, SUNY Korea - 2019 36 Questions?

CSE316 : Fund of SW Development - Tony Mione, SUNY Korea - 2019 37