From d44c9a5b7ffbcb13e7d46cc6d2606c03ca991ce3 Mon Sep 17 00:00:00 2001 From: Christian Reinbold <-> Date: Tue, 23 Nov 2021 10:50:36 +0100 Subject: [PATCH 1/2] Introduce IAircraft interface to abstract flying things with passenger and crew capacity. WIP: Tests still broken. --- src/main/java/Runner.java | 18 +++++----- .../flight/reservation/flight/Flight.java | 24 ++++---------- .../reservation/flight/ScheduledFlight.java | 31 ++++------------- .../flight/reservation/plane/A350Plane.java | 19 +++++++++++ .../flight/reservation/plane/A380Plane.java | 19 +++++++++++ .../reservation/plane/AntonovAN2Plane.java | 19 +++++++++++ .../reservation/plane/Embraer190Plane.java | 19 +++++++++++ .../reservation/plane/H1Helicopter.java | 14 ++++++++ .../reservation/plane/H2Helicopter.java | 14 ++++++++ .../flight/reservation/plane/Helicopter.java | 25 ++------------ .../plane/HypaHypePassengerDrone.java | 20 +++++++++++ .../flight/reservation/plane/IAircraft.java | 7 ++++ .../reservation/plane/PassengerDrone.java | 13 -------- .../reservation/plane/PassengerPlane.java | 33 ------------------- .../java/flight.reservation/ScenarioTest.java | 11 ++++--- .../java/flight.reservation/ScheduleTest.java | 20 +++++------ 16 files changed, 169 insertions(+), 137 deletions(-) create mode 100644 src/main/java/flight/reservation/plane/A350Plane.java create mode 100644 src/main/java/flight/reservation/plane/A380Plane.java create mode 100644 src/main/java/flight/reservation/plane/AntonovAN2Plane.java create mode 100644 src/main/java/flight/reservation/plane/Embraer190Plane.java create mode 100644 src/main/java/flight/reservation/plane/H1Helicopter.java create mode 100644 src/main/java/flight/reservation/plane/H2Helicopter.java create mode 100644 src/main/java/flight/reservation/plane/HypaHypePassengerDrone.java create mode 100644 src/main/java/flight/reservation/plane/IAircraft.java delete mode 100644 src/main/java/flight/reservation/plane/PassengerDrone.java delete mode 100644 src/main/java/flight/reservation/plane/PassengerPlane.java diff --git a/src/main/java/Runner.java b/src/main/java/Runner.java index ddea7fb..3432301 100644 --- a/src/main/java/Runner.java +++ b/src/main/java/Runner.java @@ -1,9 +1,7 @@ import flight.reservation.Airport; import flight.reservation.flight.Schedule; import flight.reservation.flight.Flight; -import flight.reservation.plane.Helicopter; -import flight.reservation.plane.PassengerDrone; -import flight.reservation.plane.PassengerPlane; +import flight.reservation.plane.*; import java.util.Arrays; import java.util.List; @@ -20,13 +18,13 @@ public class Runner { new Airport("Chengdu Shuangliu International Airport", "CTU", "Shuangliu-Wuhou, Chengdu, Sichuan") ); - static List aircrafts = Arrays.asList( - new PassengerPlane("A380"), - new PassengerPlane("A350"), - new PassengerPlane("Embraer 190"), - new PassengerPlane("Antonov AN2"), - new Helicopter("H1"), - new PassengerDrone("HypaHype") + static List aircrafts = Arrays.asList( + new A380Plane(), + new A350Plane(), + new Embraer190Plane(), + new AntonovAN2Plane(), + new H1Helicopter(), + new HypaHypePassengerDrone() ); static List flights = Arrays.asList( diff --git a/src/main/java/flight/reservation/flight/Flight.java b/src/main/java/flight/reservation/flight/Flight.java index b674511..1bf880b 100644 --- a/src/main/java/flight/reservation/flight/Flight.java +++ b/src/main/java/flight/reservation/flight/Flight.java @@ -1,9 +1,7 @@ package flight.reservation.flight; import flight.reservation.Airport; -import flight.reservation.plane.Helicopter; -import flight.reservation.plane.PassengerDrone; -import flight.reservation.plane.PassengerPlane; +import flight.reservation.plane.IAircraft; import java.util.Arrays; @@ -12,9 +10,9 @@ public class Flight { private int number; private Airport departure; private Airport arrival; - protected Object aircraft; + protected IAircraft aircraft; - public Flight(int number, Airport departure, Airport arrival, Object aircraft) throws IllegalArgumentException { + public Flight(int number, Airport departure, Airport arrival, IAircraft aircraft) throws IllegalArgumentException { this.number = number; this.departure = departure; this.arrival = arrival; @@ -29,22 +27,12 @@ private void checkValidity() throws IllegalArgumentException { } private boolean isAircraftValid(Airport airport) { - return Arrays.stream(airport.getAllowedAircrafts()).anyMatch(x -> { - String model; - if (this.aircraft instanceof PassengerPlane) { - model = ((PassengerPlane) this.aircraft).model; - } else if (this.aircraft instanceof Helicopter) { - model = ((Helicopter) this.aircraft).getModel(); - } else if (this.aircraft instanceof PassengerDrone) { - model = "HypaHype"; - } else { - throw new IllegalArgumentException(String.format("Aircraft is not recognized")); - } - return x.equals(model); + return Arrays.stream(airport.getAllowedAircrafts()).anyMatch(allowedModel -> { + return allowedModel.equals(aircraft.getModel()); }); } - public Object getAircraft() { + public IAircraft getAircraft() { return aircraft; } diff --git a/src/main/java/flight/reservation/flight/ScheduledFlight.java b/src/main/java/flight/reservation/flight/ScheduledFlight.java index 7c49d21..6ad6d4a 100644 --- a/src/main/java/flight/reservation/flight/ScheduledFlight.java +++ b/src/main/java/flight/reservation/flight/ScheduledFlight.java @@ -2,9 +2,8 @@ import flight.reservation.Airport; import flight.reservation.Passenger; -import flight.reservation.plane.Helicopter; -import flight.reservation.plane.PassengerDrone; -import flight.reservation.plane.PassengerPlane; +import flight.reservation.plane.IAircraft; +import flight.reservation.plane.HypaHypePassengerDrone; import java.util.ArrayList; import java.util.Date; @@ -16,13 +15,13 @@ public class ScheduledFlight extends Flight { private final Date departureTime; private double currentPrice = 100; - public ScheduledFlight(int number, Airport departure, Airport arrival, Object aircraft, Date departureTime) { + public ScheduledFlight(int number, Airport departure, Airport arrival, IAircraft aircraft, Date departureTime) { super(number, departure, arrival, aircraft); this.departureTime = departureTime; this.passengers = new ArrayList<>(); } - public ScheduledFlight(int number, Airport departure, Airport arrival, Object aircraft, Date departureTime, double currentPrice) { + public ScheduledFlight(int number, Airport departure, Airport arrival, IAircraft aircraft, Date departureTime, double currentPrice) { super(number, departure, arrival, aircraft); this.departureTime = departureTime; this.passengers = new ArrayList<>(); @@ -30,16 +29,7 @@ public ScheduledFlight(int number, Airport departure, Airport arrival, Object ai } public int getCrewMemberCapacity() throws NoSuchFieldException { - if (this.aircraft instanceof PassengerPlane) { - return ((PassengerPlane) this.aircraft).crewCapacity; - } - if (this.aircraft instanceof Helicopter) { - return 2; - } - if (this.aircraft instanceof PassengerDrone) { - return 0; - } - throw new NoSuchFieldException("this aircraft has no information about its crew capacity"); + return aircraft.getCrewCapacity(); } public void addPassengers(List passengers) { @@ -51,16 +41,7 @@ public void removePassengers(List passengers) { } public int getCapacity() throws NoSuchFieldException { - if (this.aircraft instanceof PassengerPlane) { - return ((PassengerPlane) this.aircraft).passengerCapacity; - } - if (this.aircraft instanceof Helicopter) { - return ((Helicopter) this.aircraft).getPassengerCapacity(); - } - if (this.aircraft instanceof PassengerDrone) { - return 4; - } - throw new NoSuchFieldException("this aircraft has no information about its capacity"); + return this.aircraft.getPassengerCapacity(); } public int getAvailableCapacity() throws NoSuchFieldException { diff --git a/src/main/java/flight/reservation/plane/A350Plane.java b/src/main/java/flight/reservation/plane/A350Plane.java new file mode 100644 index 0000000..1145f44 --- /dev/null +++ b/src/main/java/flight/reservation/plane/A350Plane.java @@ -0,0 +1,19 @@ +package flight.reservation.plane; + +public class A350Plane implements IAircraft { + + @Override + public String getModel() { + return "A350"; + } + + @Override + public int getPassengerCapacity() { + return 320; + } + + @Override + public int getCrewCapacity() { + return 40; + } +} diff --git a/src/main/java/flight/reservation/plane/A380Plane.java b/src/main/java/flight/reservation/plane/A380Plane.java new file mode 100644 index 0000000..ee58b27 --- /dev/null +++ b/src/main/java/flight/reservation/plane/A380Plane.java @@ -0,0 +1,19 @@ +package flight.reservation.plane; + +public class A380Plane implements IAircraft { + + @Override + public String getModel() { + return "A380"; + } + + @Override + public int getPassengerCapacity() { + return 500; + } + + @Override + public int getCrewCapacity() { + return 42; + } +} diff --git a/src/main/java/flight/reservation/plane/AntonovAN2Plane.java b/src/main/java/flight/reservation/plane/AntonovAN2Plane.java new file mode 100644 index 0000000..e938568 --- /dev/null +++ b/src/main/java/flight/reservation/plane/AntonovAN2Plane.java @@ -0,0 +1,19 @@ +package flight.reservation.plane; + +public class AntonovAN2Plane implements IAircraft { + + @Override + public String getModel() { + return "Antonov AN2"; + } + + @Override + public int getPassengerCapacity() { + return 15; + } + + @Override + public int getCrewCapacity() { + return 3; + } +} diff --git a/src/main/java/flight/reservation/plane/Embraer190Plane.java b/src/main/java/flight/reservation/plane/Embraer190Plane.java new file mode 100644 index 0000000..76fd9ec --- /dev/null +++ b/src/main/java/flight/reservation/plane/Embraer190Plane.java @@ -0,0 +1,19 @@ +package flight.reservation.plane; + +public class Embraer190Plane implements IAircraft { + + @Override + public String getModel() { + return "Embraer 190"; + } + + @Override + public int getPassengerCapacity() { + return 25; + } + + @Override + public int getCrewCapacity() { + return 5; + } +} diff --git a/src/main/java/flight/reservation/plane/H1Helicopter.java b/src/main/java/flight/reservation/plane/H1Helicopter.java new file mode 100644 index 0000000..be44d0a --- /dev/null +++ b/src/main/java/flight/reservation/plane/H1Helicopter.java @@ -0,0 +1,14 @@ +package flight.reservation.plane; + +public class H1Helicopter extends Helicopter { + + @Override + public String getModel() { + return "H1"; + } + + @Override + public int getPassengerCapacity() { + return 4; + } +} diff --git a/src/main/java/flight/reservation/plane/H2Helicopter.java b/src/main/java/flight/reservation/plane/H2Helicopter.java new file mode 100644 index 0000000..d5986e2 --- /dev/null +++ b/src/main/java/flight/reservation/plane/H2Helicopter.java @@ -0,0 +1,14 @@ +package flight.reservation.plane; + +public class H2Helicopter extends Helicopter { + + @Override + public String getModel() { + return "H2"; + } + + @Override + public int getPassengerCapacity() { + return 6; + } +} diff --git a/src/main/java/flight/reservation/plane/Helicopter.java b/src/main/java/flight/reservation/plane/Helicopter.java index 4add92c..a56f4f6 100644 --- a/src/main/java/flight/reservation/plane/Helicopter.java +++ b/src/main/java/flight/reservation/plane/Helicopter.java @@ -1,25 +1,6 @@ package flight.reservation.plane; -public class Helicopter { - private final String model; - private final int passengerCapacity; - - public Helicopter(String model) { - this.model = model; - if (model.equals("H1")) { - passengerCapacity = 4; - } else if (model.equals("H2")) { - passengerCapacity = 6; - } else { - throw new IllegalArgumentException(String.format("Model type '%s' is not recognized", model)); - } - } - - public String getModel() { - return model; - } - - public int getPassengerCapacity() { - return passengerCapacity; - } +public abstract class Helicopter implements IAircraft { + @Override + public int getCrewCapacity() { return 2; } } diff --git a/src/main/java/flight/reservation/plane/HypaHypePassengerDrone.java b/src/main/java/flight/reservation/plane/HypaHypePassengerDrone.java new file mode 100644 index 0000000..9ccc8e3 --- /dev/null +++ b/src/main/java/flight/reservation/plane/HypaHypePassengerDrone.java @@ -0,0 +1,20 @@ +package flight.reservation.plane; + +public class HypaHypePassengerDrone implements IAircraft { + + @Override + public String getModel() { + return "HypyHype"; + } + + + @Override + public int getPassengerCapacity() { + return 4; + } + + @Override + public int getCrewCapacity() { + return 0; + } +} diff --git a/src/main/java/flight/reservation/plane/IAircraft.java b/src/main/java/flight/reservation/plane/IAircraft.java new file mode 100644 index 0000000..5b3996c --- /dev/null +++ b/src/main/java/flight/reservation/plane/IAircraft.java @@ -0,0 +1,7 @@ +package flight.reservation.plane; + +public interface IAircraft { + String getModel(); + int getPassengerCapacity(); + int getCrewCapacity(); +} diff --git a/src/main/java/flight/reservation/plane/PassengerDrone.java b/src/main/java/flight/reservation/plane/PassengerDrone.java deleted file mode 100644 index 2f75861..0000000 --- a/src/main/java/flight/reservation/plane/PassengerDrone.java +++ /dev/null @@ -1,13 +0,0 @@ -package flight.reservation.plane; - -public class PassengerDrone { - private final String model; - - public PassengerDrone(String model) { - if (model.equals("HypaHype")) { - this.model = model; - } else { - throw new IllegalArgumentException(String.format("Model type '%s' is not recognized", model)); - } - } -} diff --git a/src/main/java/flight/reservation/plane/PassengerPlane.java b/src/main/java/flight/reservation/plane/PassengerPlane.java deleted file mode 100644 index aa4b738..0000000 --- a/src/main/java/flight/reservation/plane/PassengerPlane.java +++ /dev/null @@ -1,33 +0,0 @@ -package flight.reservation.plane; - -public class PassengerPlane { - - public String model; - public int passengerCapacity; - public int crewCapacity; - - public PassengerPlane(String model) { - this.model = model; - switch (model) { - case "A380": - passengerCapacity = 500; - crewCapacity = 42; - break; - case "A350": - passengerCapacity = 320; - crewCapacity = 40; - break; - case "Embraer 190": - passengerCapacity = 25; - crewCapacity = 5; - break; - case "Antonov AN2": - passengerCapacity = 15; - crewCapacity = 3; - break; - default: - throw new IllegalArgumentException(String.format("Model type '%s' is not recognized", model)); - } - } - -} diff --git a/src/test/java/flight.reservation/ScenarioTest.java b/src/test/java/flight.reservation/ScenarioTest.java index b22069a..db9ea98 100644 --- a/src/test/java/flight.reservation/ScenarioTest.java +++ b/src/test/java/flight.reservation/ScenarioTest.java @@ -5,8 +5,9 @@ import flight.reservation.flight.ScheduledFlight; import flight.reservation.order.FlightOrder; import flight.reservation.payment.CreditCard; -import flight.reservation.plane.Helicopter; -import flight.reservation.plane.PassengerPlane; +import flight.reservation.plane.A380Plane; +import flight.reservation.plane.H1Helicopter; +import flight.reservation.plane.IAircraft; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; @@ -57,7 +58,7 @@ public void initFlights() { @Test @DisplayName("then the flight should not be available") void thenFlightNotAvailable() { - assertThrows(IllegalArgumentException.class, () -> new Flight(1, startAirport, destinationAirport, new Helicopter("H1"))); + assertThrows(IllegalArgumentException.class, () -> new Flight(1, startAirport, destinationAirport, new H1Helicopter())); } } @@ -70,7 +71,7 @@ class FlightIsPossible { public void initFlights() { startAirport = new Airport("John F. Kennedy International Airport", "JFK", "Queens, New York, New York"); destinationAirport = new Airport("Frankfurt Airport", "FRA", "Frankfurt, Hesse"); - flight = new Flight(1, startAirport, destinationAirport, new Helicopter("H1")); + flight = new Flight(1, startAirport, destinationAirport, new H1Helicopter()); Date departure = TestUtil.addDays(Date.from(Instant.now()), 3); schedule.scheduleFlight(flight, departure); } @@ -138,7 +139,7 @@ public void init() { // flights startAirport = new Airport("Berlin Airport", "BER", "Berlin, Berlin"); destinationAirport = new Airport("Frankfurt Airport", "FRA", "Frankfurt, Hesse"); - flight = new Flight(1, startAirport, destinationAirport, new PassengerPlane("A380")); + flight = new Flight(1, startAirport, destinationAirport, new A380Plane()); Date departure = TestUtil.addDays(Date.from(Instant.now()), 3); schedule.scheduleFlight(flight, departure); // customer diff --git a/src/test/java/flight.reservation/ScheduleTest.java b/src/test/java/flight.reservation/ScheduleTest.java index 5f1a141..8102664 100644 --- a/src/test/java/flight.reservation/ScheduleTest.java +++ b/src/test/java/flight.reservation/ScheduleTest.java @@ -3,9 +3,7 @@ import flight.reservation.flight.Flight; import flight.reservation.flight.Schedule; import flight.reservation.flight.ScheduledFlight; -import flight.reservation.plane.Helicopter; -import flight.reservation.plane.PassengerDrone; -import flight.reservation.plane.PassengerPlane; +import flight.reservation.plane.*; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; @@ -55,7 +53,7 @@ void thenSearchForAnKnownElementShouldReturnNull() { @Test @DisplayName("then removing a flight should still yield an empty list") void thenScheduleShouldYieldEmpty() { - schedule.removeFlight(new Flight(1, new Airport("a", "a", "a"), new Airport("b", "b", "b"), new PassengerPlane("A380"))); + schedule.removeFlight(new Flight(1, new Airport("a", "a", "a"), new Airport("b", "b", "b"), new A380Plane())); assertEquals(0, schedule.getScheduledFlights().size()); } @@ -71,7 +69,7 @@ void scheduleOneFlight() { Airport startAirport = new Airport("Berlin Airport", "BER", "Berlin, Berlin"); Airport destAirport = new Airport("Frankfurt Airport", "FRA", "Frankfurt, Hesse"); - PassengerPlane aircraft = new PassengerPlane("A380"); + IAircraft aircraft = new A380Plane(); flight = new Flight(1, startAirport, destAirport, aircraft); departure = TestUtil.addDays(Date.from(Instant.now()), 3); schedule.scheduleFlight(flight, departure); @@ -123,12 +121,12 @@ class GivenAnExistingSchedule { ); List flights = Arrays.asList( - new Flight(1, airports.get(0), airports.get(1), new PassengerPlane("A350")), - new Flight(2, airports.get(1), airports.get(2), new PassengerPlane("A380")), - new Flight(3, airports.get(2), airports.get(4), new PassengerPlane("Embraer 190")), - new Flight(4, airports.get(3), airports.get(2), new PassengerPlane("Antonov AN2")), - new Flight(5, airports.get(4), airports.get(2), new Helicopter("H1")), - new Flight(6, airports.get(5), airports.get(7), new PassengerDrone("HypaHype")) + new Flight(1, airports.get(0), airports.get(1), new A350Plane()), + new Flight(2, airports.get(1), airports.get(2), new A380Plane()), + new Flight(3, airports.get(2), airports.get(4), new Embraer190Plane()), + new Flight(4, airports.get(3), airports.get(2), new AntonovAN2Plane()), + new Flight(5, airports.get(4), airports.get(2), new H1Helicopter()), + new Flight(6, airports.get(5), airports.get(7), new HypaHypePassengerDrone()) ); @BeforeEach From ea15d5bfdad8deff1e496cddbafe37d8339b721d Mon Sep 17 00:00:00 2001 From: Christian Reinbold <-> Date: Tue, 23 Nov 2021 10:59:41 +0100 Subject: [PATCH 2/2] Remove code duplication of valid order check. --- .../java/flight/reservation/Customer.java | 22 ++++--------------- .../flight/reservation/order/FlightOrder.java | 6 ++--- .../java/flight/reservation/order/Order.java | 4 ++-- 3 files changed, 9 insertions(+), 23 deletions(-) diff --git a/src/main/java/flight/reservation/Customer.java b/src/main/java/flight/reservation/Customer.java index 2e2c12b..cf51582 100644 --- a/src/main/java/flight/reservation/Customer.java +++ b/src/main/java/flight/reservation/Customer.java @@ -21,9 +21,6 @@ public Customer(String name, String email) { } public FlightOrder createOrder(List passengerNames, List flights, double price) { - if (!isOrderValid(passengerNames, flights)) { - throw new IllegalStateException("Order is not valid"); - } FlightOrder order = new FlightOrder(flights); order.setCustomer(this); order.setPrice(price); @@ -33,25 +30,14 @@ public FlightOrder createOrder(List passengerNames, List scheduledFlight.addPassengers(passengers)); + if (!order.isValid()) { + throw new IllegalStateException("Order is not valid"); + } + orders.add(order); return order; } - private boolean isOrderValid(List passengerNames, List flights) { - boolean valid = true; - valid = valid && !FlightOrder.getNoFlyList().contains(this.getName()); - valid = valid && passengerNames.stream().noneMatch(passenger -> FlightOrder.getNoFlyList().contains(passenger)); - valid = valid && flights.stream().allMatch(scheduledFlight -> { - try { - return scheduledFlight.getAvailableCapacity() >= passengerNames.size(); - } catch (NoSuchFieldException e) { - e.printStackTrace(); - return false; - } - }); - return valid; - } - public String getEmail() { return email; } diff --git a/src/main/java/flight/reservation/order/FlightOrder.java b/src/main/java/flight/reservation/order/FlightOrder.java index b2bdb56..ffa4171 100644 --- a/src/main/java/flight/reservation/order/FlightOrder.java +++ b/src/main/java/flight/reservation/order/FlightOrder.java @@ -25,13 +25,13 @@ public List getScheduledFlights() { return flights; } - private boolean isOrderValid(Customer customer, List passengerNames, List flights) { + public boolean isValid() { boolean valid = true; valid = valid && !noFlyList.contains(customer.getName()); - valid = valid && passengerNames.stream().noneMatch(passenger -> noFlyList.contains(passenger)); + valid = valid && passengers.stream().noneMatch(passenger -> noFlyList.contains(passenger.getName())); valid = valid && flights.stream().allMatch(scheduledFlight -> { try { - return scheduledFlight.getAvailableCapacity() >= passengerNames.size(); + return scheduledFlight.getAvailableCapacity() >= passengers.size(); } catch (NoSuchFieldException e) { e.printStackTrace(); return false; diff --git a/src/main/java/flight/reservation/order/Order.java b/src/main/java/flight/reservation/order/Order.java index baa2d00..858f142 100644 --- a/src/main/java/flight/reservation/order/Order.java +++ b/src/main/java/flight/reservation/order/Order.java @@ -11,8 +11,8 @@ public class Order { private final UUID id; private double price; private boolean isClosed = false; - private Customer customer; - private List passengers; + protected Customer customer; + protected List passengers; public Order() { this.id = UUID.randomUUID();