From 46b23f322fff5fc3ece1f92f126ac7dd4573aa33 Mon Sep 17 00:00:00 2001 From: Samil Ayoub Date: Wed, 2 Sep 2020 13:46:53 +0100 Subject: [PATCH 01/10] Add Simple Factory Pattern implementation Java source code demonstrate simple factory design pattern --- pom.xml | 1 + .../java/com/iluwatar/simplefactory/App.java | 16 ++++++++++ .../java/com/iluwatar/simplefactory/Car.java | 10 +++++++ .../simplefactory/CarSimpleFactory.java | 29 +++++++++++++++++++ .../com/iluwatar/simplefactory/Ferrari.java | 14 +++++++++ .../java/com/iluwatar/simplefactory/Ford.java | 14 +++++++++ 6 files changed, 84 insertions(+) create mode 100644 simple-factory/src/main/java/com/iluwatar/simplefactory/App.java create mode 100644 simple-factory/src/main/java/com/iluwatar/simplefactory/Car.java create mode 100644 simple-factory/src/main/java/com/iluwatar/simplefactory/CarSimpleFactory.java create mode 100644 simple-factory/src/main/java/com/iluwatar/simplefactory/Ferrari.java create mode 100644 simple-factory/src/main/java/com/iluwatar/simplefactory/Ford.java diff --git a/pom.xml b/pom.xml index 6d779700f..cc59a846a 100644 --- a/pom.xml +++ b/pom.xml @@ -195,6 +195,7 @@ arrange-act-assert transaction-script filterer + simple-factory diff --git a/simple-factory/src/main/java/com/iluwatar/simplefactory/App.java b/simple-factory/src/main/java/com/iluwatar/simplefactory/App.java new file mode 100644 index 000000000..898efe6d3 --- /dev/null +++ b/simple-factory/src/main/java/com/iluwatar/simplefactory/App.java @@ -0,0 +1,16 @@ +package com.iluwatar.simplefactory; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class App { + + private static final Logger LOGGER = LoggerFactory.getLogger(App.class); + + public static void main(String[] args) { + Car car1 = CarSimpleFactory.getCar(CarSimpleFactory.carTypes.FORD); + Car car2 = CarSimpleFactory.getCar(CarSimpleFactory.carTypes.FERRARI); + LOGGER.info(car1.getDescription()); + LOGGER.info(car2.getDescription()); + } +} diff --git a/simple-factory/src/main/java/com/iluwatar/simplefactory/Car.java b/simple-factory/src/main/java/com/iluwatar/simplefactory/Car.java new file mode 100644 index 000000000..82ff4ebe0 --- /dev/null +++ b/simple-factory/src/main/java/com/iluwatar/simplefactory/Car.java @@ -0,0 +1,10 @@ +package com.iluwatar.simplefactory; + +/** + * Car interface + */ +public interface Car { + + public String getDescription(); + +} diff --git a/simple-factory/src/main/java/com/iluwatar/simplefactory/CarSimpleFactory.java b/simple-factory/src/main/java/com/iluwatar/simplefactory/CarSimpleFactory.java new file mode 100644 index 000000000..33dbe7b88 --- /dev/null +++ b/simple-factory/src/main/java/com/iluwatar/simplefactory/CarSimpleFactory.java @@ -0,0 +1,29 @@ +package com.iluwatar.simplefactory; + + +/** + * Factory of cars + */ +public class CarSimpleFactory { + + /* + * Enumeration for different types of cars + */ + static enum carTypes { + FORD, FERRARI + }; + + /* + * Factory method takes as parameter a car type and initiate the appropriate class + */ + public static Car getCar(carTypes type) { + switch (type) { + case FORD: + return new Ford(); + case FERRARI: + return new Ferrari(); + default: + throw new IllegalArgumentException("Model not supported."); + } + } +} diff --git a/simple-factory/src/main/java/com/iluwatar/simplefactory/Ferrari.java b/simple-factory/src/main/java/com/iluwatar/simplefactory/Ferrari.java new file mode 100644 index 000000000..f9f1d8492 --- /dev/null +++ b/simple-factory/src/main/java/com/iluwatar/simplefactory/Ferrari.java @@ -0,0 +1,14 @@ +package com.iluwatar.simplefactory; + +/** + * Ferrari implementation + */ +public class Ferrari implements Car { + + static final String DESCRIPTION = "This is Ferrari."; + + @Override + public String getDescription() { + return DESCRIPTION; + } +} diff --git a/simple-factory/src/main/java/com/iluwatar/simplefactory/Ford.java b/simple-factory/src/main/java/com/iluwatar/simplefactory/Ford.java new file mode 100644 index 000000000..0adf4b66b --- /dev/null +++ b/simple-factory/src/main/java/com/iluwatar/simplefactory/Ford.java @@ -0,0 +1,14 @@ +package com.iluwatar.simplefactory; + +/** + * Ford implementation + */ +public class Ford implements Car { + + static final String DESCRIPTION = "This is Ford."; + + @Override + public String getDescription() { + return DESCRIPTION; + } +} From ac98b31b68fcdf3133041d64e38fd2478202c227 Mon Sep 17 00:00:00 2001 From: Samil Ayoub Date: Wed, 2 Sep 2020 14:09:44 +0100 Subject: [PATCH 02/10] Add Maven Assembly plugin to pom.xml --- simple-factory/pom.xml | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 simple-factory/pom.xml diff --git a/simple-factory/pom.xml b/simple-factory/pom.xml new file mode 100644 index 000000000..e7d28511f --- /dev/null +++ b/simple-factory/pom.xml @@ -0,0 +1,30 @@ + + 4.0.0 + + com.iluwatar + java-design-patterns + 1.24.0-SNAPSHOT + + simple-factory + + + + + org.apache.maven.plugins + maven-assembly-plugin + + + + + + com.iluwatar.abstractfactory.App + + + + + + + + + \ No newline at end of file From b423fd30d4b0d1fd6db2681c35f7c49ce447b1e5 Mon Sep 17 00:00:00 2001 From: Samil Ayoub Date: Wed, 2 Sep 2020 18:12:42 +0100 Subject: [PATCH 03/10] Fix bugs, clean the code and add unit tests. --- simple-factory/etc/simple-factory.urm.puml | 35 +++++++++++++++ simple-factory/pom.xml | 13 +++++- .../java/com/iluwatar/simplefactory/App.java | 44 +++++++++++++++---- .../java/com/iluwatar/simplefactory/Car.java | 8 ++-- .../simplefactory/CarSimpleFactory.java | 42 ++++++++---------- .../com/iluwatar/simplefactory/Ferrari.java | 16 +++---- .../java/com/iluwatar/simplefactory/Ford.java | 12 ++--- .../com/iluwatar/simplefactory/AppTest.java | 14 ++++++ .../simplefactory/CarSimpleFactoryTest.java | 15 +++++++ 9 files changed, 148 insertions(+), 51 deletions(-) create mode 100644 simple-factory/etc/simple-factory.urm.puml create mode 100644 simple-factory/src/test/java/com/iluwatar/simplefactory/AppTest.java create mode 100644 simple-factory/src/test/java/com/iluwatar/simplefactory/CarSimpleFactoryTest.java diff --git a/simple-factory/etc/simple-factory.urm.puml b/simple-factory/etc/simple-factory.urm.puml new file mode 100644 index 000000000..77fee4b5b --- /dev/null +++ b/simple-factory/etc/simple-factory.urm.puml @@ -0,0 +1,35 @@ +@startuml +package com.iluwatar.simplefactory { + class App { + - LOGGER : Logger {static} + + App() + + main(args : String[]) {static} + } + interface Car { + + getDescription() : String {abstract} + } + class CarSimpleFactory { + + CarSimpleFactory() + + getCar(type : CarType) : Car {static} + } + ~enum CarType { + + FERRARI {static} + + FORD {static} + + valueOf(name : String) : CarType {static} + + values() : CarType[] {static} + } + class Ferrari { + ~ DESCRIPTION : String {static} + + Ferrari() + + getDescription() : String + } + class Ford { + ~ DESCRIPTION : String {static} + + Ford() + + getDescription() : String + } +} +CarType ..+ CarSimpleFactory +Ferrari ..|> Car +Ford ..|> Car +@enduml \ No newline at end of file diff --git a/simple-factory/pom.xml b/simple-factory/pom.xml index e7d28511f..ca7c0547d 100644 --- a/simple-factory/pom.xml +++ b/simple-factory/pom.xml @@ -6,6 +6,17 @@ 1.24.0-SNAPSHOT simple-factory + + + org.junit.jupiter + junit-jupiter-engine + test + + + junit + junit + + + + org.apache.maven.plugins + maven-assembly-plugin + + + + + + com.iluwatar.factory.App + + + + + + + + + \ No newline at end of file diff --git a/factory/src/main/java/com/iluwatar/factory/App.java b/factory/src/main/java/com/iluwatar/factory/App.java new file mode 100644 index 000000000..13f217646 --- /dev/null +++ b/factory/src/main/java/com/iluwatar/factory/App.java @@ -0,0 +1,51 @@ +/* + * The MIT License + * Copyright © 2014-2019 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package com.iluwatar.factory; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Factory is an object for creating other objects, it providing Providing a static method to + * create and return objects of varying classes, in order to hide the implementation logic + * and makes client code focus on usage rather then objects initialization and management. + * + *

In this example the CarFactory is the factory class and it provides a static method to + * create different cars. + */ + +public class App { + + private static final Logger LOGGER = LoggerFactory.getLogger(App.class); + + /** + * Program main entry point. + */ + public static void main(String[] args) { + var car1 = CarsFactory.getCar(CarsFactory.CarType.FORD); + var car2 = CarsFactory.getCar(CarsFactory.CarType.FERRARI); + LOGGER.info(car1.getDescription()); + LOGGER.info(car2.getDescription()); + } +} diff --git a/factory/src/main/java/com/iluwatar/factory/Car.java b/factory/src/main/java/com/iluwatar/factory/Car.java new file mode 100644 index 000000000..6f564233c --- /dev/null +++ b/factory/src/main/java/com/iluwatar/factory/Car.java @@ -0,0 +1,10 @@ +package com.iluwatar.factory; + +/** + * Car interface. + */ +public interface Car { + + public String getDescription(); + +} diff --git a/factory/src/main/java/com/iluwatar/factory/CarsFactory.java b/factory/src/main/java/com/iluwatar/factory/CarsFactory.java new file mode 100644 index 000000000..01ad157ca --- /dev/null +++ b/factory/src/main/java/com/iluwatar/factory/CarsFactory.java @@ -0,0 +1,25 @@ +package com.iluwatar.factory; + +/** + * Factory of cars. + */ +public class CarsFactory { + + /** + * Enumeration for different types of cars. + */ + static enum CarType { + FORD, FERRARI + } + + /** + * Factory method takes as parameter a car type and initiate the appropriate class. + */ + public static Car getCar(CarType type) { + switch (type) { + case FORD: return new Ford(); + case FERRARI: return new Ferrari(); + default: throw new IllegalArgumentException("Model not supported."); + } + } +} diff --git a/factory/src/main/java/com/iluwatar/factory/Ferrari.java b/factory/src/main/java/com/iluwatar/factory/Ferrari.java new file mode 100644 index 000000000..590167f81 --- /dev/null +++ b/factory/src/main/java/com/iluwatar/factory/Ferrari.java @@ -0,0 +1,14 @@ +package com.iluwatar.factory; + +/** + * Ferrari implementation. + */ +public class Ferrari implements Car { + + static final String DESCRIPTION = "This is Ferrari."; + + @Override + public String getDescription() { + return DESCRIPTION; + } +} diff --git a/factory/src/main/java/com/iluwatar/factory/Ford.java b/factory/src/main/java/com/iluwatar/factory/Ford.java new file mode 100644 index 000000000..13ae7a49e --- /dev/null +++ b/factory/src/main/java/com/iluwatar/factory/Ford.java @@ -0,0 +1,14 @@ +package com.iluwatar.factory; + +/** + * Ford implementation. + */ +public class Ford implements Car { + + static final String DESCRIPTION = "This is Ford."; + + @Override + public String getDescription() { + return DESCRIPTION; + } +} diff --git a/factory/src/test/java/com/iluwatar/factory/AppTest.java b/factory/src/test/java/com/iluwatar/factory/AppTest.java new file mode 100644 index 000000000..d29ffb6a2 --- /dev/null +++ b/factory/src/test/java/com/iluwatar/factory/AppTest.java @@ -0,0 +1,14 @@ +package com.iluwatar.factory; + +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.Test; + +class AppTest { + + @Test + void shouldExecuteWithoutExceptions() { + assertDoesNotThrow(() -> App.main(new String[]{})); + } + +} diff --git a/factory/src/test/java/com/iluwatar/factory/CarsFactoryTest.java b/factory/src/test/java/com/iluwatar/factory/CarsFactoryTest.java new file mode 100644 index 000000000..eae75919a --- /dev/null +++ b/factory/src/test/java/com/iluwatar/factory/CarsFactoryTest.java @@ -0,0 +1,15 @@ +package com.iluwatar.factory; + +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.Test; + +class CarsFactoryTest { + + @Test + void shouldReturnFerrariInstance() { + final var ferrari = CarsFactory.getCar(CarsFactory.CarType.FERRARI); + assertTrue(ferrari instanceof Ferrari); + } + +} From 2bb252e08f3dbf74a0a11cd443fc9ac8241fa53a Mon Sep 17 00:00:00 2001 From: Samil Ayoub Date: Thu, 3 Sep 2020 22:41:55 +0100 Subject: [PATCH 06/10] Clean the code --- simple-factory/README.md | 128 ------------------ simple-factory/etc/simple-factory.urm.puml | 35 ----- simple-factory/pom.xml | 41 ------ .../java/com/iluwatar/simplefactory/App.java | 42 ------ .../java/com/iluwatar/simplefactory/Car.java | 10 -- .../simplefactory/CarSimpleFactory.java | 25 ---- .../com/iluwatar/simplefactory/Ferrari.java | 14 -- .../java/com/iluwatar/simplefactory/Ford.java | 14 -- .../com/iluwatar/simplefactory/AppTest.java | 14 -- .../simplefactory/CarSimpleFactoryTest.java | 15 -- 10 files changed, 338 deletions(-) delete mode 100644 simple-factory/README.md delete mode 100644 simple-factory/etc/simple-factory.urm.puml delete mode 100644 simple-factory/pom.xml delete mode 100644 simple-factory/src/main/java/com/iluwatar/simplefactory/App.java delete mode 100644 simple-factory/src/main/java/com/iluwatar/simplefactory/Car.java delete mode 100644 simple-factory/src/main/java/com/iluwatar/simplefactory/CarSimpleFactory.java delete mode 100644 simple-factory/src/main/java/com/iluwatar/simplefactory/Ferrari.java delete mode 100644 simple-factory/src/main/java/com/iluwatar/simplefactory/Ford.java delete mode 100644 simple-factory/src/test/java/com/iluwatar/simplefactory/AppTest.java delete mode 100644 simple-factory/src/test/java/com/iluwatar/simplefactory/CarSimpleFactoryTest.java diff --git a/simple-factory/README.md b/simple-factory/README.md deleted file mode 100644 index 1d069a6dd..000000000 --- a/simple-factory/README.md +++ /dev/null @@ -1,128 +0,0 @@ ---- -layout: pattern -title: Simple Factory -folder: simple-factory -permalink: /patterns/simple-factory/ -categories: Creational -tags: - - Gang of Four ---- - -## Also known as - -* Factory -* Static Factory Method - -## Intent - -Providing a static method encapsulated in a class called factory, in order to hide the implementation logic and makes client code focus on usage rather then initialization new objects. - -## Explanation - -Real world example - -> Lets say we have a web application connected to SQLServer, but now we want to switch to Oracle. To do so without modifying existing source code, we need to implements Simple Factory pattern, in which a static method can be invoked to create connection to a given database. - -Wikipedia says - -> Factory is an object for creating other objects – formally a factory is a function or method that returns objects of a varying prototype or class. - -**Programmatic Example** - -We have an interface "Car" and tow implementations "Ford" and "Ferrari". - -```java -/** - * Car interface. - */ -public interface Car { - - public String getDescription(); - -} - -/** - * Ford implementation. - */ -public class Ford implements Car { - - static final String DESCRIPTION = "This is Ford."; - - @Override - public String getDescription() { - return DESCRIPTION; - } -} - -/** - * Ferrari implementation. - */ -public class Ferrari implements Car { - - static final String DESCRIPTION = "This is Ferrari."; - - @Override - public String getDescription() { - return DESCRIPTION; - } -} -``` - -Then we have the static method "getCar" to create car objects encapsulated in the factory class "CarSimpleFactory". - -```java -/** - * Factory of cars. - */ -public class CarSimpleFactory { - - /** - * Enumeration for different types of cars. - */ - static enum CarType { - FORD, FERRARI - } - - /** - * Factory method takes as parameter a car type and initiate the appropriate class. - */ - public static Car getCar(CarType type) { - switch (type) { - case FORD: return new Ford(); - case FERRARI: return new Ferrari(); - default: throw new IllegalArgumentException("Model not supported."); - } - } -} -``` - -Now on the client code we can create differentes types of cars(Ford or Ferrari) using the factory class. - -```java -Car car1 = CarSimpleFactory.getCar(CarSimpleFactory.CarType.FORD); -Car car2 = CarSimpleFactory.getCar(CarSimpleFactory.CarType.FERRARI); -LOGGER.info(car1.getDescription()); -LOGGER.info(car2.getDescription()); -``` - -Program output: - -```java -This is Ford. -This Ferrari. -``` -## Applicability - -Use the Simple Factory pattern when you only care about the creation of a object, not how to create and manage it. - -## Disadvantages: - -The code becomes more complicated than it should be. - -## Related patterns - -[Factory Method](https://java-design-patterns.com/patterns/factory-method/) -[Factory Kit](https://java-design-patterns.com/patterns/factory-kit/) -[Abstract Factory](https://java-design-patterns.com/patterns/abstract-factory/) - - diff --git a/simple-factory/etc/simple-factory.urm.puml b/simple-factory/etc/simple-factory.urm.puml deleted file mode 100644 index 77fee4b5b..000000000 --- a/simple-factory/etc/simple-factory.urm.puml +++ /dev/null @@ -1,35 +0,0 @@ -@startuml -package com.iluwatar.simplefactory { - class App { - - LOGGER : Logger {static} - + App() - + main(args : String[]) {static} - } - interface Car { - + getDescription() : String {abstract} - } - class CarSimpleFactory { - + CarSimpleFactory() - + getCar(type : CarType) : Car {static} - } - ~enum CarType { - + FERRARI {static} - + FORD {static} - + valueOf(name : String) : CarType {static} - + values() : CarType[] {static} - } - class Ferrari { - ~ DESCRIPTION : String {static} - + Ferrari() - + getDescription() : String - } - class Ford { - ~ DESCRIPTION : String {static} - + Ford() - + getDescription() : String - } -} -CarType ..+ CarSimpleFactory -Ferrari ..|> Car -Ford ..|> Car -@enduml \ No newline at end of file diff --git a/simple-factory/pom.xml b/simple-factory/pom.xml deleted file mode 100644 index ca7c0547d..000000000 --- a/simple-factory/pom.xml +++ /dev/null @@ -1,41 +0,0 @@ - - 4.0.0 - - com.iluwatar - java-design-patterns - 1.24.0-SNAPSHOT - - simple-factory - - - org.junit.jupiter - junit-jupiter-engine - test - - - junit - junit - - - - - - - org.apache.maven.plugins - maven-assembly-plugin - - - - - - com.iluwatar.simplefactory.App - - - - - - - - - \ No newline at end of file diff --git a/simple-factory/src/main/java/com/iluwatar/simplefactory/App.java b/simple-factory/src/main/java/com/iluwatar/simplefactory/App.java deleted file mode 100644 index f13566ba6..000000000 --- a/simple-factory/src/main/java/com/iluwatar/simplefactory/App.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * The MIT License - * Copyright © 2014-2019 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -package com.iluwatar.simplefactory; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class App { - - private static final Logger LOGGER = LoggerFactory.getLogger(App.class); - - /** - * Program main entry point. - */ - public static void main(String[] args) { - Car car1 = CarSimpleFactory.getCar(CarSimpleFactory.CarType.FORD); - Car car2 = CarSimpleFactory.getCar(CarSimpleFactory.CarType.FERRARI); - LOGGER.info(car1.getDescription()); - LOGGER.info(car2.getDescription()); - } -} diff --git a/simple-factory/src/main/java/com/iluwatar/simplefactory/Car.java b/simple-factory/src/main/java/com/iluwatar/simplefactory/Car.java deleted file mode 100644 index b87070040..000000000 --- a/simple-factory/src/main/java/com/iluwatar/simplefactory/Car.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.iluwatar.simplefactory; - -/** - * Car interface. - */ -public interface Car { - - public String getDescription(); - -} diff --git a/simple-factory/src/main/java/com/iluwatar/simplefactory/CarSimpleFactory.java b/simple-factory/src/main/java/com/iluwatar/simplefactory/CarSimpleFactory.java deleted file mode 100644 index 911fe610f..000000000 --- a/simple-factory/src/main/java/com/iluwatar/simplefactory/CarSimpleFactory.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.iluwatar.simplefactory; - -/** - * Factory of cars. - */ -public class CarSimpleFactory { - - /** - * Enumeration for different types of cars. - */ - static enum CarType { - FORD, FERRARI - } - - /** - * Factory method takes as parameter a car type and initiate the appropriate class. - */ - public static Car getCar(CarType type) { - switch (type) { - case FORD: return new Ford(); - case FERRARI: return new Ferrari(); - default: throw new IllegalArgumentException("Model not supported."); - } - } -} diff --git a/simple-factory/src/main/java/com/iluwatar/simplefactory/Ferrari.java b/simple-factory/src/main/java/com/iluwatar/simplefactory/Ferrari.java deleted file mode 100644 index d6e865182..000000000 --- a/simple-factory/src/main/java/com/iluwatar/simplefactory/Ferrari.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.iluwatar.simplefactory; - -/** - * Ferrari implementation. - */ -public class Ferrari implements Car { - - static final String DESCRIPTION = "This is Ferrari."; - - @Override - public String getDescription() { - return DESCRIPTION; - } -} diff --git a/simple-factory/src/main/java/com/iluwatar/simplefactory/Ford.java b/simple-factory/src/main/java/com/iluwatar/simplefactory/Ford.java deleted file mode 100644 index 19cbea2ae..000000000 --- a/simple-factory/src/main/java/com/iluwatar/simplefactory/Ford.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.iluwatar.simplefactory; - -/** - * Ford implementation. - */ -public class Ford implements Car { - - static final String DESCRIPTION = "This is Ford."; - - @Override - public String getDescription() { - return DESCRIPTION; - } -} diff --git a/simple-factory/src/test/java/com/iluwatar/simplefactory/AppTest.java b/simple-factory/src/test/java/com/iluwatar/simplefactory/AppTest.java deleted file mode 100644 index 4465b3b8c..000000000 --- a/simple-factory/src/test/java/com/iluwatar/simplefactory/AppTest.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.iluwatar.simplefactory; - -import static org.junit.jupiter.api.Assertions.*; - -import org.junit.jupiter.api.Test; - -class AppTest { - - @Test - void shouldExecuteWithoutExceptions() { - assertDoesNotThrow(() -> App.main(new String[]{})); - } - -} diff --git a/simple-factory/src/test/java/com/iluwatar/simplefactory/CarSimpleFactoryTest.java b/simple-factory/src/test/java/com/iluwatar/simplefactory/CarSimpleFactoryTest.java deleted file mode 100644 index 394b652b6..000000000 --- a/simple-factory/src/test/java/com/iluwatar/simplefactory/CarSimpleFactoryTest.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.iluwatar.simplefactory; - -import static org.junit.jupiter.api.Assertions.*; - -import org.junit.jupiter.api.Test; - -class CarSimpleFactoryTest { - - @Test - void shouldReturnFerrariInstance() { - final var ferrari = CarSimpleFactory.getCar(CarSimpleFactory.CarType.FERRARI); - assertTrue(ferrari instanceof Ferrari); - } - -} From 8b26452c75a8529ef3407d643fa33a1a2799a825 Mon Sep 17 00:00:00 2001 From: Samil Ayoub Date: Thu, 3 Sep 2020 22:58:15 +0100 Subject: [PATCH 07/10] bug fixing --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index cc59a846a..da3084ab2 100644 --- a/pom.xml +++ b/pom.xml @@ -195,7 +195,7 @@ arrange-act-assert transaction-script filterer - simple-factory + factory From 6caf78e4e57fe98fde7813f9129437f530022f63 Mon Sep 17 00:00:00 2001 From: Samil Ayoub Date: Fri, 4 Sep 2020 21:21:51 +0100 Subject: [PATCH 08/10] updates : - Using lambda expression to create cars - Using spaces instead of tabs in pom.xml --- factory/README.md | 45 ++++++++++++------- factory/pom.xml | 42 ++++++++--------- .../main/java/com/iluwatar/factory/App.java | 4 +- .../java/com/iluwatar/factory/CarType.java | 22 +++++++++ .../com/iluwatar/factory/CarsFactory.java | 13 +----- .../com/iluwatar/factory/CarsFactoryTest.java | 2 +- 6 files changed, 76 insertions(+), 52 deletions(-) create mode 100644 factory/src/main/java/com/iluwatar/factory/CarType.java diff --git a/factory/README.md b/factory/README.md index 42c8838a3..62478e4a9 100644 --- a/factory/README.md +++ b/factory/README.md @@ -68,41 +68,52 @@ public class Ferrari implements Car { } ``` +Enumeration above represents types of cars that we support(Ford and Ferrari). + +```java +public enum CarType { + + /** + * Enumeration for different types of cars. + */ + FORD(Ford::new), + FERRARI(Ferrari::new); + + private final Supplier constructor; + + CarType(Supplier constructor) { + this.constructor = constructor; + } + + public Supplier getConstructor() { + return this.constructor; + } +} +``` Then we have the static method "getCar" to create car objects encapsulated in the factory class "CarSimpleFactory". ```java /** * Factory of cars. */ -public class CarSimpleFactory { - - /** - * Enumeration for different types of cars. - */ - static enum CarType { - FORD, FERRARI - } +public class CarsFactory { /** * Factory method takes as parameter a car type and initiate the appropriate class. */ public static Car getCar(CarType type) { - switch (type) { - case FORD: return new Ford(); - case FERRARI: return new Ferrari(); - default: throw new IllegalArgumentException("Model not supported."); - } + return type.getConstructor().get(); } } ``` -Now on the client code we can create differentes types of cars(Ford or Ferrari) using the factory class. +Now on the client code we can create different types of cars using the factory class. ```java -Car car1 = CarSimpleFactory.getCar(CarSimpleFactory.CarType.FORD); -Car car2 = CarSimpleFactory.getCar(CarSimpleFactory.CarType.FERRARI); +var car1 = CarsFactory.getCar(CarType.FORD); +var car2 = CarsFactory.getCar(CarType.FERRARI); LOGGER.info(car1.getDescription()); -LOGGER.info(car2.getDescription()); +LOGGER.info(car2.getDescription());; ``` Program output: diff --git a/factory/pom.xml b/factory/pom.xml index fbca994a7..2a422db90 100644 --- a/factory/pom.xml +++ b/factory/pom.xml @@ -1,23 +1,25 @@ - - 4.0.0 - - com.iluwatar - java-design-patterns - 1.24.0-SNAPSHOT - - factory - - - org.junit.jupiter - junit-jupiter-engine - test - - - junit - junit - - - + + 4.0.0 + + com.iluwatar + java-design-patterns + 1.24.0-SNAPSHOT + + factory + + + org.junit.jupiter + junit-jupiter-engine + test + + + junit + junit + + + diff --git a/factory/src/main/java/com/iluwatar/factory/App.java b/factory/src/main/java/com/iluwatar/factory/App.java index 13f217646..22c50d86d 100644 --- a/factory/src/main/java/com/iluwatar/factory/App.java +++ b/factory/src/main/java/com/iluwatar/factory/App.java @@ -43,8 +43,8 @@ public class App { * Program main entry point. */ public static void main(String[] args) { - var car1 = CarsFactory.getCar(CarsFactory.CarType.FORD); - var car2 = CarsFactory.getCar(CarsFactory.CarType.FERRARI); + var car1 = CarsFactory.getCar(CarType.FORD); + var car2 = CarsFactory.getCar(CarType.FERRARI); LOGGER.info(car1.getDescription()); LOGGER.info(car2.getDescription()); } diff --git a/factory/src/main/java/com/iluwatar/factory/CarType.java b/factory/src/main/java/com/iluwatar/factory/CarType.java new file mode 100644 index 000000000..5878025bd --- /dev/null +++ b/factory/src/main/java/com/iluwatar/factory/CarType.java @@ -0,0 +1,22 @@ +package com.iluwatar.factory; + +import java.util.function.Supplier; + +public enum CarType { + + /** + * Enumeration for different types of cars. + */ + FORD(Ford::new), + FERRARI(Ferrari::new); + + private final Supplier constructor; + + CarType(Supplier constructor) { + this.constructor = constructor; + } + + public Supplier getConstructor() { + return this.constructor; + } +} diff --git a/factory/src/main/java/com/iluwatar/factory/CarsFactory.java b/factory/src/main/java/com/iluwatar/factory/CarsFactory.java index 01ad157ca..76b83d0be 100644 --- a/factory/src/main/java/com/iluwatar/factory/CarsFactory.java +++ b/factory/src/main/java/com/iluwatar/factory/CarsFactory.java @@ -5,21 +5,10 @@ package com.iluwatar.factory; */ public class CarsFactory { - /** - * Enumeration for different types of cars. - */ - static enum CarType { - FORD, FERRARI - } - /** * Factory method takes as parameter a car type and initiate the appropriate class. */ public static Car getCar(CarType type) { - switch (type) { - case FORD: return new Ford(); - case FERRARI: return new Ferrari(); - default: throw new IllegalArgumentException("Model not supported."); - } + return type.getConstructor().get(); } } diff --git a/factory/src/test/java/com/iluwatar/factory/CarsFactoryTest.java b/factory/src/test/java/com/iluwatar/factory/CarsFactoryTest.java index eae75919a..fc823c6d4 100644 --- a/factory/src/test/java/com/iluwatar/factory/CarsFactoryTest.java +++ b/factory/src/test/java/com/iluwatar/factory/CarsFactoryTest.java @@ -8,7 +8,7 @@ class CarsFactoryTest { @Test void shouldReturnFerrariInstance() { - final var ferrari = CarsFactory.getCar(CarsFactory.CarType.FERRARI); + final var ferrari = CarsFactory.getCar(CarType.FERRARI); assertTrue(ferrari instanceof Ferrari); } From b3ef214cd62f80368698929f8814099c0ad0a3ad Mon Sep 17 00:00:00 2001 From: Samil Ayoub Date: Fri, 4 Sep 2020 22:02:19 +0100 Subject: [PATCH 09/10] Change tabs to spaces in pom.xml --- factory/pom.xml | 82 ++++++++++++++++++++++++------------------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/factory/pom.xml b/factory/pom.xml index 2a422db90..fff262458 100644 --- a/factory/pom.xml +++ b/factory/pom.xml @@ -1,43 +1,43 @@ - 4.0.0 - - com.iluwatar - java-design-patterns - 1.24.0-SNAPSHOT - - factory - - - org.junit.jupiter - junit-jupiter-engine - test - - - junit - junit - - - - - - - org.apache.maven.plugins - maven-assembly-plugin - - - - - - com.iluwatar.factory.App - - - - - - - - + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + + com.iluwatar + java-design-patterns + 1.24.0-SNAPSHOT + + factory + + + org.junit.jupiter + junit-jupiter-engine + test + + + junit + junit + + + + + + + org.apache.maven.plugins + maven-assembly-plugin + + + + + + com.iluwatar.factory.App + + + + + + + + \ No newline at end of file From bf41b1d9c98782dbb3368c44cbba934c257f483a Mon Sep 17 00:00:00 2001 From: Samil Ayoub Date: Sat, 5 Sep 2020 18:39:28 +0100 Subject: [PATCH 10/10] Updates README.md: - Adding class diagram - Adding Pros and Cons - replace "" with '' --- factory/README.md | 17 +++++++++++------ factory/etc/factory.urm.png | Bin 0 -> 25438 bytes 2 files changed, 11 insertions(+), 6 deletions(-) create mode 100644 factory/etc/factory.urm.png diff --git a/factory/README.md b/factory/README.md index 62478e4a9..9ab61b579 100644 --- a/factory/README.md +++ b/factory/README.md @@ -29,7 +29,7 @@ Wikipedia says **Programmatic Example** -We have an interface "Car" and tow implementations "Ford" and "Ferrari". +We have an interface 'Car' and tow implementations 'Ford' and 'Ferrari'. ```java /** @@ -68,7 +68,7 @@ public class Ferrari implements Car { } ``` -Enumeration above represents types of cars that we support(Ford and Ferrari). +Enumeration above represents types of cars that we support (Ford and Ferrari). ```java public enum CarType { @@ -90,7 +90,7 @@ public enum CarType { } } ``` -Then we have the static method "getCar" to create car objects encapsulated in the factory class "CarSimpleFactory". +Then we have the static method 'getCar' to create car objects encapsulated in the factory class 'CarSimpleFactory'. ```java /** @@ -122,13 +122,18 @@ Program output: This is Ford. This Ferrari. ``` -## Applicability +## Class Diagram +![alt text](./etc/factory.urm.png "Factory pattern class diagram") +## Applicability Use the Simple Factory pattern when you only care about the creation of a object, not how to create and manage it. -## Disadvantages: +## Pros +* Allows keeping all objects creation in one place and avoid of spreading 'new' key value across codebase. +* Allows to writs loosely coupled code. Some of its main advantages include better testability, easy-to-understand code, swappable components, scalability and isolated features. -The code becomes more complicated than it should be. +## Cons +* The code becomes more complicated than it should be. ## Related patterns diff --git a/factory/etc/factory.urm.png b/factory/etc/factory.urm.png new file mode 100644 index 0000000000000000000000000000000000000000..2ba39a571c4efd3d5cfd45854f0d26c843fafd8e GIT binary patch literal 25438 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 literal 0 HcmV?d00001