diff --git a/factory/README.md b/factory/README.md
new file mode 100644
index 000000000..42c8838a3
--- /dev/null
+++ b/factory/README.md
@@ -0,0 +1,128 @@
+---
+layout: pattern
+title: Factory
+folder: factory
+permalink: /patterns/factory/
+categories: Creational
+tags:
+ - Gang of Four
+---
+
+## Also known as
+
+* Simple 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/factory/etc/factory.urm.puml b/factory/etc/factory.urm.puml
new file mode 100644
index 000000000..9eded6328
--- /dev/null
+++ b/factory/etc/factory.urm.puml
@@ -0,0 +1,35 @@
+@startuml
+package com.iluwatar.factory {
+ class App {
+ - LOGGER : Logger {static}
+ + App()
+ + main(args : String[]) {static}
+ }
+ interface Car {
+ + getDescription() : String {abstract}
+ }
+ class CarsFactory {
+ + CarsFactory()
+ + 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 ..+ CarsFactory
+Ferrari ..|> Car
+Ford ..|> Car
+@enduml
\ No newline at end of file
diff --git a/factory/pom.xml b/factory/pom.xml
new file mode 100644
index 000000000..fbca994a7
--- /dev/null
+++ b/factory/pom.xml
@@ -0,0 +1,41 @@
+
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); + } + +}