From f91d74ad4ad1cd18a615d6b95d3f2d722d0e5a7a Mon Sep 17 00:00:00 2001 From: "George.Farantos" Date: Tue, 24 Jan 2023 01:44:16 +0200 Subject: [PATCH 1/2] abstract-factory: initial commit --- abstract-factory/build.gradle | 19 +++++++ abstract-factory/readme.md | 15 ++++++ .../AbstractFactoryApplication.java | 13 +++++ .../api/TransportationController.java | 34 ++++++++++++ .../dto/TransportationDto.java | 8 +++ .../dto/TransportationInput.java | 8 +++ .../enums/MeansOfTransportationEnum.java | 7 +++ .../abstractfactory/factory/Factory.java | 32 +++++++++++ .../MeansOfTransportationOfEraFactory.java | 13 +++++ .../factory/concrete/PostwarFactory.java | 26 +++++++++ .../factory/concrete/PrewarFactory.java | 26 +++++++++ .../mapper/TransportationMapper.java | 10 ++++ .../MeansOfTransport.java | 10 ++++ .../airplane/Airplane.java | 7 +++ .../airplane/PostwarAirplane.java | 32 +++++++++++ .../airplane/PrewarAirplane.java | 32 +++++++++++ .../ship/PostwarShip.java | 33 ++++++++++++ .../ship/PrewarShip.java | 33 ++++++++++++ .../meansoftransportation/ship/Ship.java | 7 +++ .../truck/PostwarTruck.java | 32 +++++++++++ .../truck/PrewarTruck.java | 32 +++++++++++ .../meansoftransportation/truck/Truck.java | 7 +++ .../service/geography/GeographyService.java | 9 ++++ .../geography/GeographyServiceImpl.java | 20 +++++++ .../service/tax/TaxService.java | 8 +++ .../service/tax/TaxServiceImpl.java | 18 +++++++ .../transportation/TransportationService.java | 8 +++ .../TransportationServiceImpl.java | 53 +++++++++++++++++++ 28 files changed, 552 insertions(+) create mode 100644 abstract-factory/build.gradle create mode 100644 abstract-factory/readme.md create mode 100644 abstract-factory/src/main/java/com/agileactors/abstractfactory/AbstractFactoryApplication.java create mode 100644 abstract-factory/src/main/java/com/agileactors/abstractfactory/api/TransportationController.java create mode 100644 abstract-factory/src/main/java/com/agileactors/abstractfactory/dto/TransportationDto.java create mode 100644 abstract-factory/src/main/java/com/agileactors/abstractfactory/dto/TransportationInput.java create mode 100644 abstract-factory/src/main/java/com/agileactors/abstractfactory/enums/MeansOfTransportationEnum.java create mode 100644 abstract-factory/src/main/java/com/agileactors/abstractfactory/factory/Factory.java create mode 100644 abstract-factory/src/main/java/com/agileactors/abstractfactory/factory/abs/MeansOfTransportationOfEraFactory.java create mode 100644 abstract-factory/src/main/java/com/agileactors/abstractfactory/factory/concrete/PostwarFactory.java create mode 100644 abstract-factory/src/main/java/com/agileactors/abstractfactory/factory/concrete/PrewarFactory.java create mode 100644 abstract-factory/src/main/java/com/agileactors/abstractfactory/mapper/TransportationMapper.java create mode 100644 abstract-factory/src/main/java/com/agileactors/abstractfactory/meansoftransportation/MeansOfTransport.java create mode 100644 abstract-factory/src/main/java/com/agileactors/abstractfactory/meansoftransportation/airplane/Airplane.java create mode 100644 abstract-factory/src/main/java/com/agileactors/abstractfactory/meansoftransportation/airplane/PostwarAirplane.java create mode 100644 abstract-factory/src/main/java/com/agileactors/abstractfactory/meansoftransportation/airplane/PrewarAirplane.java create mode 100644 abstract-factory/src/main/java/com/agileactors/abstractfactory/meansoftransportation/ship/PostwarShip.java create mode 100644 abstract-factory/src/main/java/com/agileactors/abstractfactory/meansoftransportation/ship/PrewarShip.java create mode 100644 abstract-factory/src/main/java/com/agileactors/abstractfactory/meansoftransportation/ship/Ship.java create mode 100644 abstract-factory/src/main/java/com/agileactors/abstractfactory/meansoftransportation/truck/PostwarTruck.java create mode 100644 abstract-factory/src/main/java/com/agileactors/abstractfactory/meansoftransportation/truck/PrewarTruck.java create mode 100644 abstract-factory/src/main/java/com/agileactors/abstractfactory/meansoftransportation/truck/Truck.java create mode 100644 abstract-factory/src/main/java/com/agileactors/abstractfactory/service/geography/GeographyService.java create mode 100644 abstract-factory/src/main/java/com/agileactors/abstractfactory/service/geography/GeographyServiceImpl.java create mode 100644 abstract-factory/src/main/java/com/agileactors/abstractfactory/service/tax/TaxService.java create mode 100644 abstract-factory/src/main/java/com/agileactors/abstractfactory/service/tax/TaxServiceImpl.java create mode 100644 abstract-factory/src/main/java/com/agileactors/abstractfactory/service/transportation/TransportationService.java create mode 100644 abstract-factory/src/main/java/com/agileactors/abstractfactory/service/transportation/TransportationServiceImpl.java diff --git a/abstract-factory/build.gradle b/abstract-factory/build.gradle new file mode 100644 index 0000000..891b412 --- /dev/null +++ b/abstract-factory/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'org.springframework.boot' version '2.5.1' + id 'io.spring.dependency-management' version '1.1.0' +} + +configurations { + compileOnly { + extendsFrom annotationProcessor + } +} + +dependencies { + implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.mapstruct:mapstruct:1.5.3.Final' + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok-mapstruct-binding:0.2.0' + annotationProcessor 'org.mapstruct:mapstruct-processor:1.5.3.Final' +} diff --git a/abstract-factory/readme.md b/abstract-factory/readme.md new file mode 100644 index 0000000..524bec2 --- /dev/null +++ b/abstract-factory/readme.md @@ -0,0 +1,15 @@ +### Why use the Abstract Factory Pattern + +- Use the Abstract Factory when your code needs to work with various families of related products, but you don’t want it to depend on the concrete classes of those products +- The Abstract Factory provides you with an interface for creating objects from each class of the product family. As long as your code creates objects via this interface, you don’t have to worry about creating the wrong variant of a product which doesn’t match the products already created by your app. + +#### Pros + +- You can be sure that the products you’re getting from a factory are compatible with each other. +- You avoid tight coupling between concrete products and client code. +- Single Responsibility Principle. You can extract the product creation code into one place, making the code easier to support. +- Open/Closed Principle. You can introduce new variants of products without breaking existing client code. + +#### Cons + +- The code may become more complicated than it should be, since a lot of new interfaces and classes are introduced along with the pattern. \ No newline at end of file diff --git a/abstract-factory/src/main/java/com/agileactors/abstractfactory/AbstractFactoryApplication.java b/abstract-factory/src/main/java/com/agileactors/abstractfactory/AbstractFactoryApplication.java new file mode 100644 index 0000000..5cc6b2b --- /dev/null +++ b/abstract-factory/src/main/java/com/agileactors/abstractfactory/AbstractFactoryApplication.java @@ -0,0 +1,13 @@ +package com.agileactors.abstractfactory; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class AbstractFactoryApplication { + + public static void main(String[] args) { + SpringApplication.run(AbstractFactoryApplication.class, args); + } + +} diff --git a/abstract-factory/src/main/java/com/agileactors/abstractfactory/api/TransportationController.java b/abstract-factory/src/main/java/com/agileactors/abstractfactory/api/TransportationController.java new file mode 100644 index 0000000..3d185d9 --- /dev/null +++ b/abstract-factory/src/main/java/com/agileactors/abstractfactory/api/TransportationController.java @@ -0,0 +1,34 @@ +package com.agileactors.abstractfactory.api; + +import com.agileactors.abstractfactory.dto.TransportationDto; +import com.agileactors.abstractfactory.dto.TransportationInput; +import com.agileactors.abstractfactory.mapper.TransportationMapper; +import com.agileactors.abstractfactory.service.transportation.TransportationService; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +@RequiredArgsConstructor +@RestController +@RequestMapping("/api/v1/transportation") +public class TransportationController { + + private final TransportationService transportationService; + + private final TransportationMapper transportationMapper; + + @PostMapping(value = "/{era}") + @ResponseStatus(HttpStatus.OK) + public String transportCargo(@RequestBody TransportationInput transportationInput, + @PathVariable String era) { + + TransportationDto transportationDto = transportationMapper.toDto(transportationInput); + + return transportationService.transportCargo(transportationDto, era); + } +} diff --git a/abstract-factory/src/main/java/com/agileactors/abstractfactory/dto/TransportationDto.java b/abstract-factory/src/main/java/com/agileactors/abstractfactory/dto/TransportationDto.java new file mode 100644 index 0000000..75c74c1 --- /dev/null +++ b/abstract-factory/src/main/java/com/agileactors/abstractfactory/dto/TransportationDto.java @@ -0,0 +1,8 @@ +package com.agileactors.abstractfactory.dto; + +import java.math.BigDecimal; + +public record TransportationDto(String cargo, Double quantity, BigDecimal cost, + String pointOfDeparture, String destination) { + +} diff --git a/abstract-factory/src/main/java/com/agileactors/abstractfactory/dto/TransportationInput.java b/abstract-factory/src/main/java/com/agileactors/abstractfactory/dto/TransportationInput.java new file mode 100644 index 0000000..7827d6d --- /dev/null +++ b/abstract-factory/src/main/java/com/agileactors/abstractfactory/dto/TransportationInput.java @@ -0,0 +1,8 @@ +package com.agileactors.abstractfactory.dto; + +import java.math.BigDecimal; + +public record TransportationInput(String cargo, Double quantity, BigDecimal cost, + String pointOfDeparture, String destination) { + +} diff --git a/abstract-factory/src/main/java/com/agileactors/abstractfactory/enums/MeansOfTransportationEnum.java b/abstract-factory/src/main/java/com/agileactors/abstractfactory/enums/MeansOfTransportationEnum.java new file mode 100644 index 0000000..7d6d853 --- /dev/null +++ b/abstract-factory/src/main/java/com/agileactors/abstractfactory/enums/MeansOfTransportationEnum.java @@ -0,0 +1,7 @@ +package com.agileactors.abstractfactory.enums; + +public enum MeansOfTransportationEnum { + SHIP, + AIRPLANE, + TRUCK +} diff --git a/abstract-factory/src/main/java/com/agileactors/abstractfactory/factory/Factory.java b/abstract-factory/src/main/java/com/agileactors/abstractfactory/factory/Factory.java new file mode 100644 index 0000000..687b555 --- /dev/null +++ b/abstract-factory/src/main/java/com/agileactors/abstractfactory/factory/Factory.java @@ -0,0 +1,32 @@ +package com.agileactors.abstractfactory.factory; + +import com.agileactors.abstractfactory.enums.MeansOfTransportationEnum; +import com.agileactors.abstractfactory.factory.abs.MeansOfTransportationOfEraFactory; +import com.agileactors.abstractfactory.factory.concrete.PostwarFactory; +import com.agileactors.abstractfactory.factory.concrete.PrewarFactory; +import com.agileactors.abstractfactory.meansoftransportation.MeansOfTransport; + +public class Factory { + + private Factory() { + } + + public static MeansOfTransport getMeansOfTransport( + MeansOfTransportationEnum meansOfTransportationEnum, + MeansOfTransportationOfEraFactory factory) { + + return switch (meansOfTransportationEnum) { + case AIRPLANE -> factory.createAirplane(); + case SHIP -> factory.createShip(); + default -> factory.createTruck(); + }; + } + + public static MeansOfTransportationOfEraFactory getFactoryOfEra(String era) { + if ("prewar".equals(era)) { + return new PrewarFactory(); + } + return new PostwarFactory(); + } +} + diff --git a/abstract-factory/src/main/java/com/agileactors/abstractfactory/factory/abs/MeansOfTransportationOfEraFactory.java b/abstract-factory/src/main/java/com/agileactors/abstractfactory/factory/abs/MeansOfTransportationOfEraFactory.java new file mode 100644 index 0000000..6666efe --- /dev/null +++ b/abstract-factory/src/main/java/com/agileactors/abstractfactory/factory/abs/MeansOfTransportationOfEraFactory.java @@ -0,0 +1,13 @@ +package com.agileactors.abstractfactory.factory.abs; + +import com.agileactors.abstractfactory.meansoftransportation.airplane.Airplane; +import com.agileactors.abstractfactory.meansoftransportation.ship.Ship; +import com.agileactors.abstractfactory.meansoftransportation.truck.Truck; + +public interface MeansOfTransportationOfEraFactory { + Ship createShip(); + + Airplane createAirplane(); + + Truck createTruck(); +} diff --git a/abstract-factory/src/main/java/com/agileactors/abstractfactory/factory/concrete/PostwarFactory.java b/abstract-factory/src/main/java/com/agileactors/abstractfactory/factory/concrete/PostwarFactory.java new file mode 100644 index 0000000..458a177 --- /dev/null +++ b/abstract-factory/src/main/java/com/agileactors/abstractfactory/factory/concrete/PostwarFactory.java @@ -0,0 +1,26 @@ +package com.agileactors.abstractfactory.factory.concrete; + +import com.agileactors.abstractfactory.factory.abs.MeansOfTransportationOfEraFactory; +import com.agileactors.abstractfactory.meansoftransportation.airplane.Airplane; +import com.agileactors.abstractfactory.meansoftransportation.airplane.PostwarAirplane; +import com.agileactors.abstractfactory.meansoftransportation.ship.PostwarShip; +import com.agileactors.abstractfactory.meansoftransportation.ship.Ship; +import com.agileactors.abstractfactory.meansoftransportation.truck.PostwarTruck; +import com.agileactors.abstractfactory.meansoftransportation.truck.Truck; + +public class PostwarFactory implements MeansOfTransportationOfEraFactory { + @Override + public Ship createShip() { + return new PostwarShip(); + } + + @Override + public Airplane createAirplane() { + return new PostwarAirplane(); + } + + @Override + public Truck createTruck() { + return new PostwarTruck(); + } +} diff --git a/abstract-factory/src/main/java/com/agileactors/abstractfactory/factory/concrete/PrewarFactory.java b/abstract-factory/src/main/java/com/agileactors/abstractfactory/factory/concrete/PrewarFactory.java new file mode 100644 index 0000000..62dc3a9 --- /dev/null +++ b/abstract-factory/src/main/java/com/agileactors/abstractfactory/factory/concrete/PrewarFactory.java @@ -0,0 +1,26 @@ +package com.agileactors.abstractfactory.factory.concrete; + +import com.agileactors.abstractfactory.factory.abs.MeansOfTransportationOfEraFactory; +import com.agileactors.abstractfactory.meansoftransportation.airplane.Airplane; +import com.agileactors.abstractfactory.meansoftransportation.airplane.PrewarAirplane; +import com.agileactors.abstractfactory.meansoftransportation.ship.PrewarShip; +import com.agileactors.abstractfactory.meansoftransportation.ship.Ship; +import com.agileactors.abstractfactory.meansoftransportation.truck.PrewarTruck; +import com.agileactors.abstractfactory.meansoftransportation.truck.Truck; + +public class PrewarFactory implements MeansOfTransportationOfEraFactory { + @Override + public Ship createShip() { + return new PrewarShip(); + } + + @Override + public Airplane createAirplane() { + return new PrewarAirplane(); + } + + @Override + public Truck createTruck() { + return new PrewarTruck(); + } +} diff --git a/abstract-factory/src/main/java/com/agileactors/abstractfactory/mapper/TransportationMapper.java b/abstract-factory/src/main/java/com/agileactors/abstractfactory/mapper/TransportationMapper.java new file mode 100644 index 0000000..7656223 --- /dev/null +++ b/abstract-factory/src/main/java/com/agileactors/abstractfactory/mapper/TransportationMapper.java @@ -0,0 +1,10 @@ +package com.agileactors.abstractfactory.mapper; + +import com.agileactors.abstractfactory.dto.TransportationDto; +import com.agileactors.abstractfactory.dto.TransportationInput; +import org.mapstruct.Mapper; + +@Mapper(componentModel = "spring") +public interface TransportationMapper { + TransportationDto toDto(TransportationInput input); +} \ No newline at end of file diff --git a/abstract-factory/src/main/java/com/agileactors/abstractfactory/meansoftransportation/MeansOfTransport.java b/abstract-factory/src/main/java/com/agileactors/abstractfactory/meansoftransportation/MeansOfTransport.java new file mode 100644 index 0000000..498b6e1 --- /dev/null +++ b/abstract-factory/src/main/java/com/agileactors/abstractfactory/meansoftransportation/MeansOfTransport.java @@ -0,0 +1,10 @@ +package com.agileactors.abstractfactory.meansoftransportation; + +public interface MeansOfTransport { + + public void checkCargo(String cargo); + + public void loadCargo(Double quantity); + + public void sendToDestination(String destination); +} diff --git a/abstract-factory/src/main/java/com/agileactors/abstractfactory/meansoftransportation/airplane/Airplane.java b/abstract-factory/src/main/java/com/agileactors/abstractfactory/meansoftransportation/airplane/Airplane.java new file mode 100644 index 0000000..5a4f0fb --- /dev/null +++ b/abstract-factory/src/main/java/com/agileactors/abstractfactory/meansoftransportation/airplane/Airplane.java @@ -0,0 +1,7 @@ +package com.agileactors.abstractfactory.meansoftransportation.airplane; + +import com.agileactors.abstractfactory.meansoftransportation.MeansOfTransport; + +public interface Airplane extends MeansOfTransport { + +} diff --git a/abstract-factory/src/main/java/com/agileactors/abstractfactory/meansoftransportation/airplane/PostwarAirplane.java b/abstract-factory/src/main/java/com/agileactors/abstractfactory/meansoftransportation/airplane/PostwarAirplane.java new file mode 100644 index 0000000..d2d861f --- /dev/null +++ b/abstract-factory/src/main/java/com/agileactors/abstractfactory/meansoftransportation/airplane/PostwarAirplane.java @@ -0,0 +1,32 @@ +package com.agileactors.abstractfactory.meansoftransportation.airplane; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +@AllArgsConstructor +@NoArgsConstructor +@Getter +@Slf4j +public class PostwarAirplane implements Airplane { + + private static final Double MAX_CARGO_LOAD = 12000.00; + private String name; + + public void checkCargo(String cargo) { + log.info("Checking what is needed to load cargo of type {} into the postwar airplane", cargo); + } + + public void loadCargo(Double quantity) { + if (quantity.compareTo(MAX_CARGO_LOAD) > 0) { + log.info("Loaded cargo with quantity {} into several flights to be transported.", quantity); + } else { + log.info("Loaded cargo with quantity {} into one flight.", quantity); + } + } + + public void sendToDestination(String destination) { + log.info("Sending cargo to destination {}", destination); + } +} diff --git a/abstract-factory/src/main/java/com/agileactors/abstractfactory/meansoftransportation/airplane/PrewarAirplane.java b/abstract-factory/src/main/java/com/agileactors/abstractfactory/meansoftransportation/airplane/PrewarAirplane.java new file mode 100644 index 0000000..2d2a595 --- /dev/null +++ b/abstract-factory/src/main/java/com/agileactors/abstractfactory/meansoftransportation/airplane/PrewarAirplane.java @@ -0,0 +1,32 @@ +package com.agileactors.abstractfactory.meansoftransportation.airplane; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +@AllArgsConstructor +@NoArgsConstructor +@Getter +@Slf4j +public class PrewarAirplane implements Airplane { + + private static final Double MAX_CARGO_LOAD = 6000.00; + private String name; + + public void checkCargo(String cargo) { + log.info("Checking what is needed to load cargo of type {} into the prewar airplane", cargo); + } + + public void loadCargo(Double quantity) { + if (quantity.compareTo(MAX_CARGO_LOAD) > 0) { + log.info("Loaded cargo with quantity {} into several flights to be transported.", quantity); + } else { + log.info("Loaded cargo with quantity {} into one flight.", quantity); + } + } + + public void sendToDestination(String destination) { + log.info("Sending cargo to destination {}", destination); + } +} diff --git a/abstract-factory/src/main/java/com/agileactors/abstractfactory/meansoftransportation/ship/PostwarShip.java b/abstract-factory/src/main/java/com/agileactors/abstractfactory/meansoftransportation/ship/PostwarShip.java new file mode 100644 index 0000000..a06fb64 --- /dev/null +++ b/abstract-factory/src/main/java/com/agileactors/abstractfactory/meansoftransportation/ship/PostwarShip.java @@ -0,0 +1,33 @@ +package com.agileactors.abstractfactory.meansoftransportation.ship; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +@AllArgsConstructor +@NoArgsConstructor +@Getter +@Slf4j +public class PostwarShip implements Ship { + + private static final Double MAX_CARGO_LOAD = 23000.00; + private String name; + + public void checkCargo(String cargo) { + log.info("Checking what is needed to load cargo of type {} into the postwar ship", cargo); + } + + public void loadCargo(Double quantity) { + if (quantity.compareTo(MAX_CARGO_LOAD) > 0) { + log.info("Loaded cargo with quantity {} into several postwar ships to be transported.", + quantity); + } else { + log.info("Loaded cargo with quantity {} into one postwar ship.", quantity); + } + } + + public void sendToDestination(String destination) { + log.info("Sending cargo to port {}", destination); + } +} diff --git a/abstract-factory/src/main/java/com/agileactors/abstractfactory/meansoftransportation/ship/PrewarShip.java b/abstract-factory/src/main/java/com/agileactors/abstractfactory/meansoftransportation/ship/PrewarShip.java new file mode 100644 index 0000000..8e657b1 --- /dev/null +++ b/abstract-factory/src/main/java/com/agileactors/abstractfactory/meansoftransportation/ship/PrewarShip.java @@ -0,0 +1,33 @@ +package com.agileactors.abstractfactory.meansoftransportation.ship; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +@AllArgsConstructor +@NoArgsConstructor +@Getter +@Slf4j +public class PrewarShip implements Ship { + + private static final Double MAX_CARGO_LOAD = 13000.00; + private String name; + + public void checkCargo(String cargo) { + log.info("Checking what is needed to load cargo of type {} into the prewar ship", cargo); + } + + public void loadCargo(Double quantity) { + if (quantity.compareTo(MAX_CARGO_LOAD) > 0) { + log.info("Loaded cargo with quantity {} into several prewar ships to be transported.", + quantity); + } else { + log.info("Loaded cargo with quantity {} into one prewar ship.", quantity); + } + } + + public void sendToDestination(String destination) { + log.info("Sending cargo to port {}", destination); + } +} diff --git a/abstract-factory/src/main/java/com/agileactors/abstractfactory/meansoftransportation/ship/Ship.java b/abstract-factory/src/main/java/com/agileactors/abstractfactory/meansoftransportation/ship/Ship.java new file mode 100644 index 0000000..8dddb38 --- /dev/null +++ b/abstract-factory/src/main/java/com/agileactors/abstractfactory/meansoftransportation/ship/Ship.java @@ -0,0 +1,7 @@ +package com.agileactors.abstractfactory.meansoftransportation.ship; + +import com.agileactors.abstractfactory.meansoftransportation.MeansOfTransport; + +public interface Ship extends MeansOfTransport { + +} diff --git a/abstract-factory/src/main/java/com/agileactors/abstractfactory/meansoftransportation/truck/PostwarTruck.java b/abstract-factory/src/main/java/com/agileactors/abstractfactory/meansoftransportation/truck/PostwarTruck.java new file mode 100644 index 0000000..a8ce058 --- /dev/null +++ b/abstract-factory/src/main/java/com/agileactors/abstractfactory/meansoftransportation/truck/PostwarTruck.java @@ -0,0 +1,32 @@ +package com.agileactors.abstractfactory.meansoftransportation.truck; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +@AllArgsConstructor +@NoArgsConstructor +@Getter +@Slf4j +public class PostwarTruck implements Truck { + + private static final Double MAX_CARGO_LOAD = 1200.00; + private String licensePlate; + + public void checkCargo(String cargo) { + log.info("Checking what is needed to load cargo of type {}", cargo); + } + + public void loadCargo(Double quantity) { + if (quantity.compareTo(MAX_CARGO_LOAD) > 0) { + log.info("Loaded cargo with quantity {} into several postwar trucks.", quantity); + } else { + log.info("Loaded cargo with quantity {} into one postwar truck.", quantity); + } + } + + public void sendToDestination(String destination) { + log.info("Sending cargo to destination {}", destination); + } +} diff --git a/abstract-factory/src/main/java/com/agileactors/abstractfactory/meansoftransportation/truck/PrewarTruck.java b/abstract-factory/src/main/java/com/agileactors/abstractfactory/meansoftransportation/truck/PrewarTruck.java new file mode 100644 index 0000000..4d8b7fb --- /dev/null +++ b/abstract-factory/src/main/java/com/agileactors/abstractfactory/meansoftransportation/truck/PrewarTruck.java @@ -0,0 +1,32 @@ +package com.agileactors.abstractfactory.meansoftransportation.truck; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +@AllArgsConstructor +@NoArgsConstructor +@Getter +@Slf4j +public class PrewarTruck implements Truck { + + private static final Double MAX_CARGO_LOAD = 1200.00; + private String licensePlate; + + public void checkCargo(String cargo) { + log.info("Checking what is needed to load cargo of type {}", cargo); + } + + public void loadCargo(Double quantity) { + if (quantity.compareTo(MAX_CARGO_LOAD) > 0) { + log.info("Loaded cargo with quantity {} into several prewar trucks.", quantity); + } else { + log.info("Loaded cargo with quantity {} into one prewar truck.", quantity); + } + } + + public void sendToDestination(String destination) { + log.info("Sending cargo to destination {}", destination); + } +} diff --git a/abstract-factory/src/main/java/com/agileactors/abstractfactory/meansoftransportation/truck/Truck.java b/abstract-factory/src/main/java/com/agileactors/abstractfactory/meansoftransportation/truck/Truck.java new file mode 100644 index 0000000..cc08f8b --- /dev/null +++ b/abstract-factory/src/main/java/com/agileactors/abstractfactory/meansoftransportation/truck/Truck.java @@ -0,0 +1,7 @@ +package com.agileactors.abstractfactory.meansoftransportation.truck; + +import com.agileactors.abstractfactory.meansoftransportation.MeansOfTransport; + +public interface Truck extends MeansOfTransport { +} + diff --git a/abstract-factory/src/main/java/com/agileactors/abstractfactory/service/geography/GeographyService.java b/abstract-factory/src/main/java/com/agileactors/abstractfactory/service/geography/GeographyService.java new file mode 100644 index 0000000..463f799 --- /dev/null +++ b/abstract-factory/src/main/java/com/agileactors/abstractfactory/service/geography/GeographyService.java @@ -0,0 +1,9 @@ +package com.agileactors.abstractfactory.service.geography; + +import com.agileactors.abstractfactory.enums.MeansOfTransportationEnum; + +public interface GeographyService { + + MeansOfTransportationEnum getMeansOfTransportation(String pointOfDeparture, + String destination); +} diff --git a/abstract-factory/src/main/java/com/agileactors/abstractfactory/service/geography/GeographyServiceImpl.java b/abstract-factory/src/main/java/com/agileactors/abstractfactory/service/geography/GeographyServiceImpl.java new file mode 100644 index 0000000..bcfdf9b --- /dev/null +++ b/abstract-factory/src/main/java/com/agileactors/abstractfactory/service/geography/GeographyServiceImpl.java @@ -0,0 +1,20 @@ +package com.agileactors.abstractfactory.service.geography; + +import com.agileactors.abstractfactory.enums.MeansOfTransportationEnum; +import org.springframework.stereotype.Service; + +@Service +public class GeographyServiceImpl implements GeographyService { + + @Override + public MeansOfTransportationEnum getMeansOfTransportation(String pointOfDeparture, + String destination) { + if (pointOfDeparture.compareTo(destination) > 0) { + return MeansOfTransportationEnum.SHIP; + } else if (pointOfDeparture.length() > 10) { + return MeansOfTransportationEnum.AIRPLANE; + } else { + return MeansOfTransportationEnum.TRUCK; + } + } +} diff --git a/abstract-factory/src/main/java/com/agileactors/abstractfactory/service/tax/TaxService.java b/abstract-factory/src/main/java/com/agileactors/abstractfactory/service/tax/TaxService.java new file mode 100644 index 0000000..5d2573f --- /dev/null +++ b/abstract-factory/src/main/java/com/agileactors/abstractfactory/service/tax/TaxService.java @@ -0,0 +1,8 @@ +package com.agileactors.abstractfactory.service.tax; + +import java.math.BigDecimal; + +public interface TaxService { + + public BigDecimal applyTaxesOnCargo(String cargo, BigDecimal net); +} diff --git a/abstract-factory/src/main/java/com/agileactors/abstractfactory/service/tax/TaxServiceImpl.java b/abstract-factory/src/main/java/com/agileactors/abstractfactory/service/tax/TaxServiceImpl.java new file mode 100644 index 0000000..e8060ec --- /dev/null +++ b/abstract-factory/src/main/java/com/agileactors/abstractfactory/service/tax/TaxServiceImpl.java @@ -0,0 +1,18 @@ +package com.agileactors.abstractfactory.service.tax; + +import java.math.BigDecimal; +import lombok.AllArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@AllArgsConstructor +public class TaxServiceImpl implements TaxService { + + @Override + public BigDecimal applyTaxesOnCargo(String cargo, BigDecimal net) { + if (cargo.startsWith("A")) { + return net.add(net.multiply(BigDecimal.valueOf(0.13))); + } + return net.add(net.multiply(BigDecimal.valueOf(0.23))); + } +} diff --git a/abstract-factory/src/main/java/com/agileactors/abstractfactory/service/transportation/TransportationService.java b/abstract-factory/src/main/java/com/agileactors/abstractfactory/service/transportation/TransportationService.java new file mode 100644 index 0000000..15862e5 --- /dev/null +++ b/abstract-factory/src/main/java/com/agileactors/abstractfactory/service/transportation/TransportationService.java @@ -0,0 +1,8 @@ +package com.agileactors.abstractfactory.service.transportation; + +import com.agileactors.abstractfactory.dto.TransportationDto; + +public interface TransportationService { + + String transportCargo(TransportationDto transportationDto, String era); +} diff --git a/abstract-factory/src/main/java/com/agileactors/abstractfactory/service/transportation/TransportationServiceImpl.java b/abstract-factory/src/main/java/com/agileactors/abstractfactory/service/transportation/TransportationServiceImpl.java new file mode 100644 index 0000000..6bcee44 --- /dev/null +++ b/abstract-factory/src/main/java/com/agileactors/abstractfactory/service/transportation/TransportationServiceImpl.java @@ -0,0 +1,53 @@ +package com.agileactors.abstractfactory.service.transportation; + +import com.agileactors.abstractfactory.dto.TransportationDto; +import com.agileactors.abstractfactory.enums.MeansOfTransportationEnum; +import com.agileactors.abstractfactory.factory.Factory; +import com.agileactors.abstractfactory.factory.abs.MeansOfTransportationOfEraFactory; +import com.agileactors.abstractfactory.meansoftransportation.MeansOfTransport; +import com.agileactors.abstractfactory.service.geography.GeographyService; +import com.agileactors.abstractfactory.service.tax.TaxService; +import java.math.BigDecimal; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +@Slf4j +public class TransportationServiceImpl implements TransportationService { + + private final TaxService taxService; + private final GeographyService geographyService; + + @Override + public String transportCargo(TransportationDto transportationDto, String era) { + + MeansOfTransportationOfEraFactory meansOfTransportationOfEraFactory = + Factory.getFactoryOfEra(era); + + MeansOfTransportationEnum meansOfTransportEnum = + geographyService.getMeansOfTransportation(transportationDto.pointOfDeparture(), + transportationDto.destination()); + + MeansOfTransport meansOfTransport = + Factory.getMeansOfTransport(meansOfTransportEnum, + meansOfTransportationOfEraFactory); + + log.info("Transporting cargo {} of quantity {} and net cost {} via {}...", + transportationDto.cargo(), transportationDto.quantity(), transportationDto.cost(), + meansOfTransportEnum); + + meansOfTransport.checkCargo(transportationDto.cargo()); + + BigDecimal finalPrice = + taxService.applyTaxesOnCargo(transportationDto.cargo(), transportationDto.cost()); + log.info("Final price after taxing is {} ", finalPrice); + + meansOfTransport.loadCargo(transportationDto.quantity()); + meansOfTransport.sendToDestination(transportationDto.destination()); + + return "Cargo was transported successfully via " + meansOfTransportEnum; + } + +} From 936a3e21a7c14430932d5700f5ae1f675c592eba Mon Sep 17 00:00:00 2001 From: "George.Farantos" Date: Wed, 25 Jan 2023 15:34:17 +0200 Subject: [PATCH 2/2] clean-up and updated read.me --- factory/readme.md | 15 ++++++++++++++- .../factory/common/service/tax/TaxService.java | 2 +- .../factory/v1/api/TransportationController.java | 1 - .../meansoftransportation/MeansOfTransport.java | 6 +++--- 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/factory/readme.md b/factory/readme.md index b541603..f3d80ec 100644 --- a/factory/readme.md +++ b/factory/readme.md @@ -21,4 +21,17 @@ - getInstance() method of java.util.Calendar, NumberFormat, and ResourceBundle uses factory method design pattern. - All the wrapper classes like Integer, Boolean etc, in Java uses this pattern to evaluate the values using valueOf() - method \ No newline at end of file + method + +### Explaining the app + +- The current app is a Spring Boot application that exposes a REST API for a company that transports different kind of + cargos from a place to another. In the first version, things are simple: we only transport via truck so the + Transportation + service instantiates a Truck object to do some actions on the cargo and transport it. In the second version, things + are + more complicated as company has expanded, and it uses a Geography service that decides how to transport the cargo. + Based + on the response it instantiates different object and then perform the same actions. This second version depicts + exactly the + problem that Factory tries to solve. The final third version applies the Factory pattern in the previous messy code. \ No newline at end of file diff --git a/factory/src/main/java/com/agileactors/factory/common/service/tax/TaxService.java b/factory/src/main/java/com/agileactors/factory/common/service/tax/TaxService.java index 81b55cd..951f584 100644 --- a/factory/src/main/java/com/agileactors/factory/common/service/tax/TaxService.java +++ b/factory/src/main/java/com/agileactors/factory/common/service/tax/TaxService.java @@ -4,5 +4,5 @@ public interface TaxService { - public BigDecimal applyTaxesOnCargo(String cargo, BigDecimal net); + BigDecimal applyTaxesOnCargo(String cargo, BigDecimal net); } diff --git a/factory/src/main/java/com/agileactors/factory/v1/api/TransportationController.java b/factory/src/main/java/com/agileactors/factory/v1/api/TransportationController.java index 722c58b..28a888c 100644 --- a/factory/src/main/java/com/agileactors/factory/v1/api/TransportationController.java +++ b/factory/src/main/java/com/agileactors/factory/v1/api/TransportationController.java @@ -5,7 +5,6 @@ import com.agileactors.factory.common.mapper.TransportationMapper; import com.agileactors.factory.v1.service.transportation.TransportationService; import lombok.RequiredArgsConstructor; -import org.mapstruct.Qualifier; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; diff --git a/factory/src/main/java/com/agileactors/factory/v3/meansoftransportation/MeansOfTransport.java b/factory/src/main/java/com/agileactors/factory/v3/meansoftransportation/MeansOfTransport.java index 73a939f..f6b8f7d 100644 --- a/factory/src/main/java/com/agileactors/factory/v3/meansoftransportation/MeansOfTransport.java +++ b/factory/src/main/java/com/agileactors/factory/v3/meansoftransportation/MeansOfTransport.java @@ -2,9 +2,9 @@ public interface MeansOfTransport { - public void checkCargo(String cargo); + void checkCargo(String cargo); - public void loadCargo(Double quantity); + void loadCargo(Double quantity); - public void sendToDestination(String destination); + void sendToDestination(String destination); }