From e83cdfc6cb3e1592768d51ed5b924491745b2cfb Mon Sep 17 00:00:00 2001 From: bethrobson Date: Mon, 6 Jan 2020 18:34:49 -0800 Subject: [PATCH] adding files for Bootcamp II --- .../designpatterns/bridge/remote/Client.java | 22 ++++++ .../bridge/remote/GenericRemote.java | 15 ++++ .../designpatterns/bridge/remote/LG.java | 18 +++++ .../bridge/remote/RemoteControl.java | 28 ++++++++ .../designpatterns/bridge/remote/Sony.java | 18 +++++ .../bridge/remote/SpecialRemote.java | 15 ++++ .../designpatterns/bridge/remote/TV.java | 8 +++ .../bridge/remote/TVFactory.java | 13 ++++ .../builder/pizza/MeatLoversPizzaBuilder.java | 40 +++++++++++ .../designpatterns/builder/pizza/Pizza.java | 50 +++++++++++++ .../builder/pizza/PizzaBuilder.java | 24 +++++++ .../builder/pizza/PizzaDirector.java | 56 +++++++++++++++ .../pizza/VeggieLoversPizzaBuilder.java | 41 +++++++++++ .../builder/vacation/Accommodation.java | 27 +++++++ .../builder/vacation/CityVacationBuilder.java | 32 +++++++++ .../builder/vacation/Hotel.java | 21 ++++++ .../vacation/OutdoorsVacationBuilder.java | 32 +++++++++ .../builder/vacation/Reservation.java | 21 ++++++ .../designpatterns/builder/vacation/Tent.java | 21 ++++++ .../builder/vacation/Vacation.java | 33 +++++++++ .../builder/vacation/VacationBuilder.java | 24 +++++++ .../builder/vacation/VacationDirector.java | 22 ++++++ .../designpatterns/command/diner/Cook.java | 14 ++++ .../command/diner/Customer.java | 11 +++ .../designpatterns/command/diner/Diner.java | 12 ++++ .../designpatterns/command/diner/Order.java | 6 ++ .../command/diner/Waitress.java | 10 +++ .../command/swing/SwingCommandExample.java | 71 +++++++++++++++++++ .../designpatterns/flyweight/Client.java | 22 ++++++ .../designpatterns/flyweight/ConiferTree.java | 8 +++ .../flyweight/DeciduousTree.java | 13 ++++ .../designpatterns/flyweight/Tree.java | 11 +++ .../designpatterns/flyweight/TreeFactory.java | 18 +++++ .../designpatterns/prototype/Client.java | 29 ++++++++ .../designpatterns/prototype/Dragon.java | 12 ++++ .../designpatterns/prototype/Drakon.java | 16 +++++ .../designpatterns/prototype/Monster.java | 26 +++++++ 37 files changed, 860 insertions(+) create mode 100644 src/headfirst/designpatterns/bridge/remote/Client.java create mode 100644 src/headfirst/designpatterns/bridge/remote/GenericRemote.java create mode 100644 src/headfirst/designpatterns/bridge/remote/LG.java create mode 100644 src/headfirst/designpatterns/bridge/remote/RemoteControl.java create mode 100644 src/headfirst/designpatterns/bridge/remote/Sony.java create mode 100644 src/headfirst/designpatterns/bridge/remote/SpecialRemote.java create mode 100644 src/headfirst/designpatterns/bridge/remote/TV.java create mode 100644 src/headfirst/designpatterns/bridge/remote/TVFactory.java create mode 100644 src/headfirst/designpatterns/builder/pizza/MeatLoversPizzaBuilder.java create mode 100755 src/headfirst/designpatterns/builder/pizza/Pizza.java create mode 100644 src/headfirst/designpatterns/builder/pizza/PizzaBuilder.java create mode 100755 src/headfirst/designpatterns/builder/pizza/PizzaDirector.java create mode 100644 src/headfirst/designpatterns/builder/pizza/VeggieLoversPizzaBuilder.java create mode 100644 src/headfirst/designpatterns/builder/vacation/Accommodation.java create mode 100644 src/headfirst/designpatterns/builder/vacation/CityVacationBuilder.java create mode 100644 src/headfirst/designpatterns/builder/vacation/Hotel.java create mode 100644 src/headfirst/designpatterns/builder/vacation/OutdoorsVacationBuilder.java create mode 100644 src/headfirst/designpatterns/builder/vacation/Reservation.java create mode 100644 src/headfirst/designpatterns/builder/vacation/Tent.java create mode 100755 src/headfirst/designpatterns/builder/vacation/Vacation.java create mode 100644 src/headfirst/designpatterns/builder/vacation/VacationBuilder.java create mode 100755 src/headfirst/designpatterns/builder/vacation/VacationDirector.java create mode 100644 src/headfirst/designpatterns/command/diner/Cook.java create mode 100644 src/headfirst/designpatterns/command/diner/Customer.java create mode 100644 src/headfirst/designpatterns/command/diner/Diner.java create mode 100755 src/headfirst/designpatterns/command/diner/Order.java create mode 100644 src/headfirst/designpatterns/command/diner/Waitress.java create mode 100755 src/headfirst/designpatterns/command/swing/SwingCommandExample.java create mode 100644 src/headfirst/designpatterns/flyweight/Client.java create mode 100644 src/headfirst/designpatterns/flyweight/ConiferTree.java create mode 100644 src/headfirst/designpatterns/flyweight/DeciduousTree.java create mode 100644 src/headfirst/designpatterns/flyweight/Tree.java create mode 100644 src/headfirst/designpatterns/flyweight/TreeFactory.java create mode 100644 src/headfirst/designpatterns/prototype/Client.java create mode 100644 src/headfirst/designpatterns/prototype/Dragon.java create mode 100644 src/headfirst/designpatterns/prototype/Drakon.java create mode 100644 src/headfirst/designpatterns/prototype/Monster.java diff --git a/src/headfirst/designpatterns/bridge/remote/Client.java b/src/headfirst/designpatterns/bridge/remote/Client.java new file mode 100644 index 00000000..868f32ae --- /dev/null +++ b/src/headfirst/designpatterns/bridge/remote/Client.java @@ -0,0 +1,22 @@ +package headfirst.designpatterns.bridge.remote; + +public class Client { + public static void main(String[] args) { + TVFactory tvFactory = new TVFactory(); + SpecialRemote remoteSony = new SpecialRemote(tvFactory); + System.out.println("Connect your remote to the TV"); + remoteSony.setTV("Sony"); + remoteSony.on(); + remoteSony.up(); + remoteSony.down(); + remoteSony.off(); + + GenericRemote remoteLG = new GenericRemote(tvFactory); + System.out.println("Connect your remote to the TV"); + remoteLG.setTV("LG"); + remoteLG.on(); + remoteLG.nextChannel(); + remoteLG.prevChannel(); + remoteLG.off(); + } +} \ No newline at end of file diff --git a/src/headfirst/designpatterns/bridge/remote/GenericRemote.java b/src/headfirst/designpatterns/bridge/remote/GenericRemote.java new file mode 100644 index 00000000..e454efa6 --- /dev/null +++ b/src/headfirst/designpatterns/bridge/remote/GenericRemote.java @@ -0,0 +1,15 @@ +package headfirst.designpatterns.bridge.remote; + +public class GenericRemote extends RemoteControl { + public GenericRemote(TVFactory tvFactory) { + super(tvFactory); + } + public void nextChannel() { + int channel = this.getChannel(); + this.setChannel(channel+1); + } + public void prevChannel() { + int channel = this.getChannel(); + this.setChannel(channel-1); + } +} \ No newline at end of file diff --git a/src/headfirst/designpatterns/bridge/remote/LG.java b/src/headfirst/designpatterns/bridge/remote/LG.java new file mode 100644 index 00000000..d1784911 --- /dev/null +++ b/src/headfirst/designpatterns/bridge/remote/LG.java @@ -0,0 +1,18 @@ +package headfirst.designpatterns.bridge.remote; + +public class LG extends TV { + int channel = 1; + public void on() { + System.out.println("Turning on the LG TV"); + } + public void off() { + System.out.println("Turning off the LG TV"); + } + public void tuneChannel(int channel) { + this.channel = channel; + System.out.println("Set the LG TV Channel to " + this.channel); + } + public int getChannel() { + return channel; + } +} \ No newline at end of file diff --git a/src/headfirst/designpatterns/bridge/remote/RemoteControl.java b/src/headfirst/designpatterns/bridge/remote/RemoteControl.java new file mode 100644 index 00000000..f673d5b7 --- /dev/null +++ b/src/headfirst/designpatterns/bridge/remote/RemoteControl.java @@ -0,0 +1,28 @@ +package headfirst.designpatterns.bridge.remote; + +public abstract class RemoteControl { + TV tv; + TVFactory tvFactory; + public RemoteControl(TVFactory tvFactory) { + this.tvFactory = tvFactory; + } + public void on() { + this.tv.on(); + } + public void off() { + this.tv.off(); + } + public void setChannel(int channel) { + tv.tuneChannel(channel); + } + public int getChannel() { + return tv.getChannel(); + } + public void setTV(String type) { + try { + tv = tvFactory.getTV(type); + } catch (Exception e) { + System.out.println(e); + } + } +} \ No newline at end of file diff --git a/src/headfirst/designpatterns/bridge/remote/Sony.java b/src/headfirst/designpatterns/bridge/remote/Sony.java new file mode 100644 index 00000000..ebf9807f --- /dev/null +++ b/src/headfirst/designpatterns/bridge/remote/Sony.java @@ -0,0 +1,18 @@ +package headfirst.designpatterns.bridge.remote; + +public class Sony extends TV { + int station = 0; + public void on() { + System.out.println("Turning on the Sony TV"); + } + public void off() { + System.out.println("Turning off the Sony TV"); + } + public void tuneChannel(int channel) { + this.station = channel; + System.out.println("Set the Sony TV station to " + this.station); + } + public int getChannel() { + return station; + } +} \ No newline at end of file diff --git a/src/headfirst/designpatterns/bridge/remote/SpecialRemote.java b/src/headfirst/designpatterns/bridge/remote/SpecialRemote.java new file mode 100644 index 00000000..adb2cdaf --- /dev/null +++ b/src/headfirst/designpatterns/bridge/remote/SpecialRemote.java @@ -0,0 +1,15 @@ +package headfirst.designpatterns.bridge.remote; + +public class SpecialRemote extends RemoteControl { + public SpecialRemote(TVFactory tvFactory) { + super(tvFactory); + } + public void up() { + int channel = this.getChannel(); + this.setChannel(channel+1); + } + public void down() { + int channel = this.getChannel(); + this.setChannel(channel-1); + } +} \ No newline at end of file diff --git a/src/headfirst/designpatterns/bridge/remote/TV.java b/src/headfirst/designpatterns/bridge/remote/TV.java new file mode 100644 index 00000000..78832d05 --- /dev/null +++ b/src/headfirst/designpatterns/bridge/remote/TV.java @@ -0,0 +1,8 @@ +package headfirst.designpatterns.bridge.remote; + +public abstract class TV { + public abstract void on(); + public abstract void off(); + public abstract void tuneChannel(int channel); + public abstract int getChannel(); +} \ No newline at end of file diff --git a/src/headfirst/designpatterns/bridge/remote/TVFactory.java b/src/headfirst/designpatterns/bridge/remote/TVFactory.java new file mode 100644 index 00000000..fe03da64 --- /dev/null +++ b/src/headfirst/designpatterns/bridge/remote/TVFactory.java @@ -0,0 +1,13 @@ +package headfirst.designpatterns.bridge.remote; + +public class TVFactory { + public TV getTV(String type) throws Exception { + if (type.equals("LG")) { + return new LG(); + } else if (type.equals("Sony")) { + return new Sony(); + } else { + throw new Exception("Invalid TV Type"); + } + } +} \ No newline at end of file diff --git a/src/headfirst/designpatterns/builder/pizza/MeatLoversPizzaBuilder.java b/src/headfirst/designpatterns/builder/pizza/MeatLoversPizzaBuilder.java new file mode 100644 index 00000000..64b2b75a --- /dev/null +++ b/src/headfirst/designpatterns/builder/pizza/MeatLoversPizzaBuilder.java @@ -0,0 +1,40 @@ +package headfirst.designpatterns.builder.pizza; + +public class MeatLoversPizzaBuilder extends PizzaBuilder { + public MeatLoversPizzaBuilder() { + this.name = "Meat Lovers Pizza"; + } + public PizzaBuilder addCheese() { + // meat lovers like moz + this.toppings.add("mozzerella"); + return this; + } + public PizzaBuilder addSauce() { + this.toppings.add("NY style sauce"); + return this; + } + public PizzaBuilder addTomatoes() { + this.toppings.add("sliced tomatoes"); + return this; + } + public PizzaBuilder addGarlic() { + this.toppings.add("garlic"); + return this; + } + public PizzaBuilder addOlives() { + // never add olives to meat lovers pizza + return this; + } + public PizzaBuilder addSpinach() { + // never add spinach to meat lovers pizza + return this; + } + public PizzaBuilder addPepperoni() { + this.toppings.add("pepperoni"); + return this; + } + public PizzaBuilder addSausage() { + this.toppings.add("sausage"); + return this; + } +} \ No newline at end of file diff --git a/src/headfirst/designpatterns/builder/pizza/Pizza.java b/src/headfirst/designpatterns/builder/pizza/Pizza.java new file mode 100755 index 00000000..5b879767 --- /dev/null +++ b/src/headfirst/designpatterns/builder/pizza/Pizza.java @@ -0,0 +1,50 @@ +package headfirst.designpatterns.builder.pizza; + +import java.util.*; + +public class Pizza { + String name; + List toppings; + + void addToppings(List toppings) { + this.toppings = toppings; + } + + void prepare() { + System.out.println("Prepare " + name); + System.out.println("Tossing dough..."); + System.out.println("Adding sauce..."); + System.out.println("Adding toppings: "); + for (String topping : toppings) { + System.out.println(" " + topping); + } + } + + void bake() { + System.out.println("Bake for 25 minutes at 350"); + } + + void cut() { + System.out.println("Cut the pizza into diagonal slices"); + } + + void box() { + System.out.println("Place pizza in official PizzaStore box"); + } + + public void setName(String name) { + this.name = name; + } + + public String toString() { + StringBuffer display = new StringBuffer(); + display.append("---- " + this.name + " ----\n"); + for (String topping : toppings) { + display.append(topping + "\n"); + } + return display.toString(); + } +} + + + diff --git a/src/headfirst/designpatterns/builder/pizza/PizzaBuilder.java b/src/headfirst/designpatterns/builder/pizza/PizzaBuilder.java new file mode 100644 index 00000000..b09ace24 --- /dev/null +++ b/src/headfirst/designpatterns/builder/pizza/PizzaBuilder.java @@ -0,0 +1,24 @@ +package headfirst.designpatterns.builder.pizza; + +import java.util.ArrayList; +import java.util.List; + +public abstract class PizzaBuilder { + String name; + List toppings = new ArrayList(); + + public abstract PizzaBuilder addCheese(); + public abstract PizzaBuilder addSauce(); + public abstract PizzaBuilder addTomatoes(); + public abstract PizzaBuilder addGarlic(); + public abstract PizzaBuilder addOlives(); + public abstract PizzaBuilder addSpinach(); + public abstract PizzaBuilder addPepperoni(); + public abstract PizzaBuilder addSausage(); + public Pizza build() { + Pizza pizza = new Pizza(); + pizza.setName(this.name); + pizza.addToppings(toppings); + return pizza; + } +} \ No newline at end of file diff --git a/src/headfirst/designpatterns/builder/pizza/PizzaDirector.java b/src/headfirst/designpatterns/builder/pizza/PizzaDirector.java new file mode 100755 index 00000000..56ecb99d --- /dev/null +++ b/src/headfirst/designpatterns/builder/pizza/PizzaDirector.java @@ -0,0 +1,56 @@ +package headfirst.designpatterns.builder.pizza; + +public class PizzaDirector { + + // Fluent Interface pattern (return the builder each time so we can string the calls together) + // Builder pattern (we have two different builders so the "same construction process can create + // different representations"). + // Builder is a solution to the telescoping constructor anti-pattern, where we have multiple, + // complex constructor methods with various args for all various combinations of options + // in construction options. + + // in this example main() is the construct() method + public static void main(String[] args) { + // Could hand builders to PizzaStore which would take the customer's order, + // and call appropriate methods for each topping, then call the + // pizza methods to prep and return to the customer. + PizzaBuilder veggieBuilder = new VeggieLoversPizzaBuilder(); + // The PizzaDirector calls the methods in the correct order to + // build a veggiePizza. + Pizza veggie = veggieBuilder.addSauce().addCheese().addOlives().addTomatoes().addSausage().build(); + veggie.prepare(); + veggie.bake(); + veggie.cut(); + veggie.box(); + System.out.println(veggie); + + PizzaBuilder meatBuilder = new MeatLoversPizzaBuilder(); + // The PizzaDirector calls the methods in the correct order to build + // a meat lovers Pizza + Pizza meat = meatBuilder.addSauce().addTomatoes().addCheese().addSausage().addPepperoni().build(); + meat.prepare(); + meat.bake(); + meat.cut(); + meat.box(); + System.out.println(meat); + + // There is some difference of opinion about StringBuilder and whether it's using + // the Builder pattern or not. Some say yes, some say no. + // StringBuilder does not provide an abstract API with multiple subclasses for + // creating different representations (variations). So, strictly, no, it doesn't + // use the Builder Pattern, but rather the Fluent Interface Pattern. + StringBuilder sb = new StringBuilder(); + sb.append("\nTesting String Builder\n").append(veggie).insert(0, "===="); + System.out.println("Length of the String Builder: " + sb.length()); + System.out.println("Result of the String Builder: " + sb.toString()); + + String sb2 = new StringBuilder().append("\nTesting String Builder\n").append(meat).insert(0, "====").toString(); + System.out.println(sb2); + + // Builder has similarities to Abstract Factory. + // But difference is that Builder provides a step by step API for building a product; + // the client is responsible for calling the steps, and those can vary in order, etc. + // With Builder, the client must have more knowledge of the details of the product being built. + // Product implementations can be swapped for others; clients don't change because the use the abstract API. + } +} diff --git a/src/headfirst/designpatterns/builder/pizza/VeggieLoversPizzaBuilder.java b/src/headfirst/designpatterns/builder/pizza/VeggieLoversPizzaBuilder.java new file mode 100644 index 00000000..fbbd03a8 --- /dev/null +++ b/src/headfirst/designpatterns/builder/pizza/VeggieLoversPizzaBuilder.java @@ -0,0 +1,41 @@ +package headfirst.designpatterns.builder.pizza; + +public class VeggieLoversPizzaBuilder extends PizzaBuilder { + public VeggieLoversPizzaBuilder() { + this.name = "Veggie Lovers Pizza"; + } + public PizzaBuilder addCheese() { + // veggie lovers like parm + this.toppings.add("parmesan"); + return this; + } + public PizzaBuilder addSauce() { + this.toppings.add("sauce"); + return this; + } + public PizzaBuilder addTomatoes() { + this.toppings.add("chopped tomatoes"); + return this; + } + public PizzaBuilder addGarlic() { + this.toppings.add("garlic"); + return this; + } + public PizzaBuilder addOlives() { + this.toppings.add("green olives"); + return this; + } + public PizzaBuilder addSpinach() { + this.toppings.add("spinach"); + return this; + } + public PizzaBuilder addPepperoni() { + // never EVER add Pepperoni to veggie lovers pizza + return this; + } + public PizzaBuilder addSausage() { + // never EVER add Sausage to veggie lovers pizza + return this; + } + +} \ No newline at end of file diff --git a/src/headfirst/designpatterns/builder/vacation/Accommodation.java b/src/headfirst/designpatterns/builder/vacation/Accommodation.java new file mode 100644 index 00000000..505b0865 --- /dev/null +++ b/src/headfirst/designpatterns/builder/vacation/Accommodation.java @@ -0,0 +1,27 @@ +package headfirst.designpatterns.builder.vacation; + +public abstract class Accommodation { + String name; + Reservation reservation = null; + + public void setReservation(Reservation r) { + this.reservation = r; + } + public Reservation getReservation() { + return this.reservation; + } + public abstract String getLocation(); + public String toString() { + StringBuffer display = new StringBuffer(); + display.append("You're staying at " + name); + if (this.reservation != null) { + display.append("\nYou have a reservation for arrival date: " + reservation.getArrivalDate() + + ", staying for " + reservation.getNights() + " nights"); + } + if (this.getLocation() != "") { + display.append(" in " + this.getLocation()); + } + display.append("\n"); + return display.toString(); + } +} \ No newline at end of file diff --git a/src/headfirst/designpatterns/builder/vacation/CityVacationBuilder.java b/src/headfirst/designpatterns/builder/vacation/CityVacationBuilder.java new file mode 100644 index 00000000..834ef60c --- /dev/null +++ b/src/headfirst/designpatterns/builder/vacation/CityVacationBuilder.java @@ -0,0 +1,32 @@ +package headfirst.designpatterns.builder.vacation; + +import java.time.LocalDate; + +public class CityVacationBuilder extends VacationBuilder { + public CityVacationBuilder() { + this.name = "City Vacation Builder"; + } + public VacationBuilder addAccommodation() { + this.accommodations.add(new Hotel()); + return this; + } + public VacationBuilder addAccommodation(String name) { + this.accommodations.add(new Hotel(name)); + return this; + } + public VacationBuilder addAccommodation(String name, int year, int month, int day, int nights, int location) { + Reservation reservation = new Reservation(); + reservation.setArrivalDate(year, month, day); + reservation.setNights(nights); + + Hotel hotel = new Hotel(name); + hotel.setReservation(reservation); + hotel.setRoomNumber(location); + this.accommodations.add(hotel); + return this; + } + public VacationBuilder addEvent(String event) { + this.events.add("See the " + event + " show"); + return this; + } +} \ No newline at end of file diff --git a/src/headfirst/designpatterns/builder/vacation/Hotel.java b/src/headfirst/designpatterns/builder/vacation/Hotel.java new file mode 100644 index 00000000..21f96ce5 --- /dev/null +++ b/src/headfirst/designpatterns/builder/vacation/Hotel.java @@ -0,0 +1,21 @@ +package headfirst.designpatterns.builder.vacation; + +public class Hotel extends Accommodation { + int roomNumber; + public Hotel() { + this.name = "Hotel"; + } + public Hotel(String name) { + this.name = name; + } + public void setRoomNumber(int n) { + this.roomNumber = n; + } + public int getRoomNumber() { + return this.roomNumber; + } + public String getLocation() { + if (roomNumber == 0) return ""; + else return "Room number " + this.roomNumber; + } +} \ No newline at end of file diff --git a/src/headfirst/designpatterns/builder/vacation/OutdoorsVacationBuilder.java b/src/headfirst/designpatterns/builder/vacation/OutdoorsVacationBuilder.java new file mode 100644 index 00000000..778b51fb --- /dev/null +++ b/src/headfirst/designpatterns/builder/vacation/OutdoorsVacationBuilder.java @@ -0,0 +1,32 @@ +package headfirst.designpatterns.builder.vacation; + +import java.time.LocalDate; + +public class OutdoorsVacationBuilder extends VacationBuilder { + public OutdoorsVacationBuilder() { + this.name = "Outdoorsy Vacation Builder"; + } + public VacationBuilder addAccommodation() { + this.accommodations.add(new Tent()); + return this; + } + public VacationBuilder addAccommodation(String name) { + this.accommodations.add(new Tent(name)); + return this; + } + public VacationBuilder addAccommodation(String name, int year, int month, int day, int nights, int location) { + Reservation reservation = new Reservation(); + reservation.setArrivalDate(year, month, day); + reservation.setNights(nights); + + Tent tent = new Tent(name); + tent.setReservation(reservation); + tent.setSiteNumber(location); + this.accommodations.add(tent); + return this; + } + public VacationBuilder addEvent(String event) { + this.events.add("Hike: " + event); + return this; + } +} \ No newline at end of file diff --git a/src/headfirst/designpatterns/builder/vacation/Reservation.java b/src/headfirst/designpatterns/builder/vacation/Reservation.java new file mode 100644 index 00000000..67ae2237 --- /dev/null +++ b/src/headfirst/designpatterns/builder/vacation/Reservation.java @@ -0,0 +1,21 @@ +package headfirst.designpatterns.builder.vacation; + +import java.time.LocalDate; + +public class Reservation { + LocalDate arrivalDate; + int nights; + + public void setArrivalDate(int year, int month, int day) { + this.arrivalDate = LocalDate.of(year, month, day); + } + public LocalDate getArrivalDate() { + return this.arrivalDate; + } + public void setNights(int nights) { + this.nights = nights; + } + public int getNights() { + return this.nights; + } +} \ No newline at end of file diff --git a/src/headfirst/designpatterns/builder/vacation/Tent.java b/src/headfirst/designpatterns/builder/vacation/Tent.java new file mode 100644 index 00000000..c9085cbf --- /dev/null +++ b/src/headfirst/designpatterns/builder/vacation/Tent.java @@ -0,0 +1,21 @@ +package headfirst.designpatterns.builder.vacation; + +public class Tent extends Accommodation { + int siteNumber; + public Tent() { + this.name = "Tent"; + } + public Tent(String name) { + this.name = name; + } + public void setSiteNumber(int n) { + this.siteNumber = n; + } + public int getSiteNumber() { + return this.siteNumber; + } + public String getLocation() { + if (siteNumber == 0) return ""; + else return "Site number " + this.siteNumber; + } +} \ No newline at end of file diff --git a/src/headfirst/designpatterns/builder/vacation/Vacation.java b/src/headfirst/designpatterns/builder/vacation/Vacation.java new file mode 100755 index 00000000..daac698c --- /dev/null +++ b/src/headfirst/designpatterns/builder/vacation/Vacation.java @@ -0,0 +1,33 @@ +package headfirst.designpatterns.builder.vacation; + +import java.util.*; + +public class Vacation { + String name; + List accommodations = new ArrayList(); + List events = new ArrayList(); + + public void setName(String name) { + this.name = name; + } + public void setAccommodations(List accommodations) { + this.accommodations = accommodations; + } + public void setEvents(List events) { + this.events = events; + } + public String toString() { + StringBuffer display = new StringBuffer(); + display.append("---- " + this.name + " ----\n"); + for (Accommodation a : accommodations) { + display.append(a); + } + for (String e : events) { + display.append(e + "\n"); + } + return display.toString(); + } +} + + + diff --git a/src/headfirst/designpatterns/builder/vacation/VacationBuilder.java b/src/headfirst/designpatterns/builder/vacation/VacationBuilder.java new file mode 100644 index 00000000..ccaac0ba --- /dev/null +++ b/src/headfirst/designpatterns/builder/vacation/VacationBuilder.java @@ -0,0 +1,24 @@ +package headfirst.designpatterns.builder.vacation; + +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; + +public abstract class VacationBuilder { + String name; + List accommodations = new ArrayList(); + List events = new ArrayList(); + + public abstract VacationBuilder addAccommodation(); + public abstract VacationBuilder addAccommodation(String name); + public abstract VacationBuilder addAccommodation(String name, int year, int month, int day, int nights, int location); + public abstract VacationBuilder addEvent(String event); + + public Vacation getVacation() { + Vacation vacation = new Vacation(); + vacation.setName(name); + vacation.setAccommodations(accommodations); + vacation.setEvents(events); + return vacation; + } +} \ No newline at end of file diff --git a/src/headfirst/designpatterns/builder/vacation/VacationDirector.java b/src/headfirst/designpatterns/builder/vacation/VacationDirector.java new file mode 100755 index 00000000..10971ecd --- /dev/null +++ b/src/headfirst/designpatterns/builder/vacation/VacationDirector.java @@ -0,0 +1,22 @@ +package headfirst.designpatterns.builder.vacation; + +public class VacationDirector { + public static void main(String[] args) { + VacationBuilder outdoorsyVacationBuilder = new OutdoorsVacationBuilder(); + Vacation outdoorsyVacation = outdoorsyVacationBuilder + .addAccommodation("Two person tent", 2020, 7, 1, 5, 34) + .addEvent("Beach") + .addAccommodation("Two person tent") + .addEvent("Mountains") + .getVacation(); + System.out.println(outdoorsyVacation); + + VacationBuilder cityVacationBuilder = new CityVacationBuilder(); + Vacation cityVacation = cityVacationBuilder + .addAccommodation("Grand Facadian", 2020, 8, 1, 5, 0) + .addAccommodation("Hotel Commander", 2020, 8, 6, 2, 0) + .addEvent("Cirque du Soleil") + .getVacation(); + System.out.println(cityVacation); + } +} diff --git a/src/headfirst/designpatterns/command/diner/Cook.java b/src/headfirst/designpatterns/command/diner/Cook.java new file mode 100644 index 00000000..7df06633 --- /dev/null +++ b/src/headfirst/designpatterns/command/diner/Cook.java @@ -0,0 +1,14 @@ +package headfirst.designpatterns.command.diner; + +public class Cook { + + public Cook() {} + + public void makeBurger() { + System.out.println("Making a burger"); + } + + public void makeFries() { + System.out.println("Making fries"); + } +} \ No newline at end of file diff --git a/src/headfirst/designpatterns/command/diner/Customer.java b/src/headfirst/designpatterns/command/diner/Customer.java new file mode 100644 index 00000000..10c3995c --- /dev/null +++ b/src/headfirst/designpatterns/command/diner/Customer.java @@ -0,0 +1,11 @@ +package headfirst.designpatterns.command.diner; + +public class Customer { + Waitress waitress; + public Customer(Waitress waitress) { + this.waitress = waitress; + } + public void hungry(Order o) { + waitress.takeOrder(o); + } +} \ No newline at end of file diff --git a/src/headfirst/designpatterns/command/diner/Diner.java b/src/headfirst/designpatterns/command/diner/Diner.java new file mode 100644 index 00000000..e917ea47 --- /dev/null +++ b/src/headfirst/designpatterns/command/diner/Diner.java @@ -0,0 +1,12 @@ +package headfirst.designpatterns.command.diner; + +public class Diner { + public static void main(String[] args) { + Cook cook = new Cook(); + Waitress waitress = new Waitress(); + Customer customer = new Customer(waitress); + + Order o = () -> { cook.makeBurger(); cook.makeFries(); }; + customer.hungry(o); + } +} \ No newline at end of file diff --git a/src/headfirst/designpatterns/command/diner/Order.java b/src/headfirst/designpatterns/command/diner/Order.java new file mode 100755 index 00000000..2bcad5e6 --- /dev/null +++ b/src/headfirst/designpatterns/command/diner/Order.java @@ -0,0 +1,6 @@ +package headfirst.designpatterns.command.diner; + +@FunctionalInterface +public interface Order { + public void orderUp(); +} diff --git a/src/headfirst/designpatterns/command/diner/Waitress.java b/src/headfirst/designpatterns/command/diner/Waitress.java new file mode 100644 index 00000000..c53025c5 --- /dev/null +++ b/src/headfirst/designpatterns/command/diner/Waitress.java @@ -0,0 +1,10 @@ +package headfirst.designpatterns.command.diner; + +public class Waitress { + Order order; + public Waitress() {} + public void takeOrder(Order order) { + this.order = order; + order.orderUp(); + } +} \ No newline at end of file diff --git a/src/headfirst/designpatterns/command/swing/SwingCommandExample.java b/src/headfirst/designpatterns/command/swing/SwingCommandExample.java new file mode 100755 index 00000000..37279784 --- /dev/null +++ b/src/headfirst/designpatterns/command/swing/SwingCommandExample.java @@ -0,0 +1,71 @@ +package headfirst.designpatterns.command.swing; + +import java.awt.*; +import javax.swing.*; + +public class SwingCommandExample { + JFrame frame; + JPanel panel; + + public static void main(String[] args) { + SwingCommandExample example = new SwingCommandExample(); + example.go(); + } + + public void go() { + frame = new JFrame(); + panel = new JPanel(); + + // The GUI is the client + // The buttons are the invokers + JButton onButton = new JButton("On"); + JButton offButton = new JButton("Off"); + + // The light is the receiver + JLabel light = new JLabel("light"); + light.setOpaque(true); + light.setBackground(Color.LIGHT_GRAY); + + // The lambdas (ActionListeners) are the commands & actionPerformed() method implementation in one. + // We use addActionListener() to set the commands and code for the actionPerformed() method + // in the invokers (the buttons) + // The interface that all the commands (listeners) implement is the ActionListener interface. + // This interface has one method, actionPerformed(). + // This is equivalent to the execute() method. + // The buttons invoke the actionPerformed() method when they are clicked, which is the method + // we implemented in the command (the listeners) + // This method which executes the code to run on the receiver, the light. + onButton.addActionListener(event -> + light.setBackground(Color.YELLOW) + ); + offButton.addActionListener(event -> + light.setBackground(Color.LIGHT_GRAY) + ); + // Set frame properties + frame.setContentPane(panel); + panel.add(onButton); + panel.add(light); + panel.add(offButton); + + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setSize(300,300); + frame.setVisible(true); + } + + /* + * Remove these two inner classes to use lambda expressions instead. + * + class AngelListener implements ActionListener { + public void actionPerformed(ActionEvent event) { + System.out.println("Don't do it, you might regret it!"); + } + } + + class DevilListener implements ActionListener { + public void actionPerformed(ActionEvent event) { + System.out.println("Come on, do it!"); + } + } + */ + +} diff --git a/src/headfirst/designpatterns/flyweight/Client.java b/src/headfirst/designpatterns/flyweight/Client.java new file mode 100644 index 00000000..09500d2d --- /dev/null +++ b/src/headfirst/designpatterns/flyweight/Client.java @@ -0,0 +1,22 @@ +package headfirst.designpatterns.flyweight; + +public class Client { + public static void main(String[] args) { + int[][] deciduousLocations = {{1, 1}, {33, 50}, {100, 90}}; + int[][] coniferLocations = {{10, 87}, {24, 76}, {2, 64}}; + TreeFactory treeFactory = new TreeFactory(); // creates the two flyweights + Tree d, c; + try { + d = treeFactory.getTree("deciduous"); + c = treeFactory.getTree("conifer"); + for (int[] location : deciduousLocations) { + d.display(location[0], location[1]); + } + for (int[] location : coniferLocations) { + c.display(location[0], location[1]); + } + } catch (Exception e) { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/src/headfirst/designpatterns/flyweight/ConiferTree.java b/src/headfirst/designpatterns/flyweight/ConiferTree.java new file mode 100644 index 00000000..e2861eda --- /dev/null +++ b/src/headfirst/designpatterns/flyweight/ConiferTree.java @@ -0,0 +1,8 @@ +package headfirst.designpatterns.flyweight; + +public class ConiferTree implements Tree { + // Complex trunk, branch, needle graphic data + public void display(int x, int y) { + System.out.println("Conifer tree is located at " + x + ", " + y); + } +} \ No newline at end of file diff --git a/src/headfirst/designpatterns/flyweight/DeciduousTree.java b/src/headfirst/designpatterns/flyweight/DeciduousTree.java new file mode 100644 index 00000000..4ac61c40 --- /dev/null +++ b/src/headfirst/designpatterns/flyweight/DeciduousTree.java @@ -0,0 +1,13 @@ +package headfirst.designpatterns.flyweight; + +import java.time.*; + +public class DeciduousTree implements Tree { + // complex trunk, branch, leaf graphic data + public void display(int x, int y) { + System.out.println("Deciduous tree is located at " + x + ", " + y); + if (!this.isWithinRange(LocalDate.now())) { + System.out.println("The tree currently has no leaves"); + } + } +} \ No newline at end of file diff --git a/src/headfirst/designpatterns/flyweight/Tree.java b/src/headfirst/designpatterns/flyweight/Tree.java new file mode 100644 index 00000000..8e42f65e --- /dev/null +++ b/src/headfirst/designpatterns/flyweight/Tree.java @@ -0,0 +1,11 @@ +package headfirst.designpatterns.flyweight; + +import java.time.*; + +public interface Tree { + public void display(int x, int y); + public default boolean isWithinRange(LocalDate aDate) { + Month month = aDate.getMonth(); + return (month.getValue() > 2) && (month.getValue() < 11); + } +} \ No newline at end of file diff --git a/src/headfirst/designpatterns/flyweight/TreeFactory.java b/src/headfirst/designpatterns/flyweight/TreeFactory.java new file mode 100644 index 00000000..c158215f --- /dev/null +++ b/src/headfirst/designpatterns/flyweight/TreeFactory.java @@ -0,0 +1,18 @@ +package headfirst.designpatterns.flyweight; + +public class TreeFactory { + Tree d, c = null; + public TreeFactory() { + this.d = new DeciduousTree(); + this.c = new ConiferTree(); + } + public Tree getTree(String type) throws Exception { + if (type.equals("deciduous")) { + return this.d; + } else if (type.equals("conifer")) { + return this.c; + } else { + throw new Exception("Invalid kind of tree"); + } + } +} \ No newline at end of file diff --git a/src/headfirst/designpatterns/prototype/Client.java b/src/headfirst/designpatterns/prototype/Client.java new file mode 100644 index 00000000..847aacdc --- /dev/null +++ b/src/headfirst/designpatterns/prototype/Client.java @@ -0,0 +1,29 @@ +package headfirst.designpatterns.prototype; + +public class Client { + public static void main(String[] args) { + Monster dragon = new Dragon("Dragon", false); // prototype for all Dragons + Monster drakon = new Drakon("Drakon", 2, true); // prototype for all Drakons + + Monster laconian = makeMonster(drakon, "Laconian"); + Monster ladon = makeMonster(dragon, "Ladon"); + + System.out.println(ladon); + ladon.spitPoison(); + + System.out.println(laconian); + laconian.spitPoison(); + } + + public static Monster makeMonster(Monster monsterToCopy, String name) { + Monster newMonster = null; + try { + newMonster = monsterToCopy.copy(); + newMonster.setName(name); + } catch (CloneNotSupportedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return newMonster; + } +} \ No newline at end of file diff --git a/src/headfirst/designpatterns/prototype/Dragon.java b/src/headfirst/designpatterns/prototype/Dragon.java new file mode 100644 index 00000000..788d3476 --- /dev/null +++ b/src/headfirst/designpatterns/prototype/Dragon.java @@ -0,0 +1,12 @@ +package headfirst.designpatterns.prototype; + +public class Dragon extends Monster { + public Dragon(String name, boolean hasWings) { + super(name); + this.hasWings = hasWings; + } + // Each concrete monster could determine how best to clone itself + public Monster copy() throws CloneNotSupportedException { + return (Monster)this.clone(); + } +} \ No newline at end of file diff --git a/src/headfirst/designpatterns/prototype/Drakon.java b/src/headfirst/designpatterns/prototype/Drakon.java new file mode 100644 index 00000000..de18482a --- /dev/null +++ b/src/headfirst/designpatterns/prototype/Drakon.java @@ -0,0 +1,16 @@ +package headfirst.designpatterns.prototype; + +public class Drakon extends Monster { + public Drakon(String name, int numHeads, boolean canBreatheFire) { + super(name); + this.numHeads = numHeads; + this.canBreatheFire = canBreatheFire; + } + public void spitPoison() { + System.out.println(this.name + " spits poison"); + } + // Each concrete monster could determine how best to clone itself + public Monster copy() throws CloneNotSupportedException { + return (Monster)this.clone(); + } +} \ No newline at end of file diff --git a/src/headfirst/designpatterns/prototype/Monster.java b/src/headfirst/designpatterns/prototype/Monster.java new file mode 100644 index 00000000..000d7c40 --- /dev/null +++ b/src/headfirst/designpatterns/prototype/Monster.java @@ -0,0 +1,26 @@ +package headfirst.designpatterns.prototype; + +public abstract class Monster implements Cloneable { + boolean eatsChildren = true; + boolean hasWings = false; + int numHeads = 1; + boolean canBreatheFire = false; + String name; + public Monster(String name) { + this.name = name; + } + public void spitPoison() { } // default is do nothing + public void setName(String name) { + this.name = name; + } + + public abstract Monster copy() throws CloneNotSupportedException; + + public String toString() { + StringBuffer s = new StringBuffer("I'm a monster named " + this.name + " with " + this.numHeads + " head(s). "); + if (this.canBreatheFire) { s.append("I can breathe fire. "); } + if (this.eatsChildren) { s.append("I eat children. "); } + if (this.hasWings) { s.append("I have wings. "); } + return s.toString(); + } +} \ No newline at end of file