diff --git a/patterns/hexagonal/pom.xml b/patterns/hexagonal/pom.xml
new file mode 100644
index 0000000000..7f6cbf176b
--- /dev/null
+++ b/patterns/hexagonal/pom.xml
@@ -0,0 +1,17 @@
+
+
+ 4.0.0
+ hexagonal
+ 1.0
+ hexagonal
+ A quick and practical example of Hexagonal Architecture in Java
+
+
+ com.baeldung
+ parent-java
+ 0.0.1-SNAPSHOT
+ ../../parent-java
+
+
+
diff --git a/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/WeatherForecasterApp.java b/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/WeatherForecasterApp.java
new file mode 100644
index 0000000000..fb21f9a877
--- /dev/null
+++ b/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/WeatherForecasterApp.java
@@ -0,0 +1,17 @@
+package com.baeldung.pattern.hexagonal;
+
+import com.baeldung.pattern.hexagonal.repository.RepositoryFactory;
+import com.baeldung.pattern.hexagonal.repository.WeatherRepository;
+import com.baeldung.pattern.hexagonal.service.WeatherForecasterService;
+import com.baeldung.pattern.hexagonal.ui.WeatherForecasterConsoleUI;
+import com.baeldung.pattern.hexagonal.ui.WeatherForecasterUI;
+
+public class WeatherForecasterApp {
+ public static void main(String[] args) {
+ WeatherRepository repository = RepositoryFactory.getMockWeatherRepository();
+ WeatherForecasterService service = new WeatherForecasterService(repository);
+ WeatherForecasterUI ui = new WeatherForecasterConsoleUI(service);
+
+ ui.start();
+ }
+}
diff --git a/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/repository/MockWeatherRepository.java b/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/repository/MockWeatherRepository.java
new file mode 100644
index 0000000000..cdb68b9086
--- /dev/null
+++ b/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/repository/MockWeatherRepository.java
@@ -0,0 +1,17 @@
+package com.baeldung.pattern.hexagonal.repository;
+
+public class MockWeatherRepository implements WeatherRepository {
+ @Override
+ public double getTemperature(String location) {
+ switch (location) {
+ case "cluj-napoca":
+ return 17;
+ case "bucharest":
+ return 22;
+ case "new york":
+ return 15;
+ default:
+ return 20;
+ }
+ }
+}
diff --git a/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/repository/RepositoryFactory.java b/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/repository/RepositoryFactory.java
new file mode 100644
index 0000000000..d1c74f4b6d
--- /dev/null
+++ b/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/repository/RepositoryFactory.java
@@ -0,0 +1,11 @@
+package com.baeldung.pattern.hexagonal.repository;
+
+public class RepositoryFactory {
+ private RepositoryFactory() {
+ super();
+ }
+
+ public static WeatherRepository getMockWeatherRepository() {
+ return new MockWeatherRepository();
+ }
+}
diff --git a/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/repository/WeatherRepository.java b/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/repository/WeatherRepository.java
new file mode 100644
index 0000000000..4c41c712ec
--- /dev/null
+++ b/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/repository/WeatherRepository.java
@@ -0,0 +1,5 @@
+package com.baeldung.pattern.hexagonal.repository;
+
+public interface WeatherRepository {
+ double getTemperature(String location);
+}
diff --git a/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/service/WeatherForecasterService.java b/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/service/WeatherForecasterService.java
new file mode 100644
index 0000000000..c39f01235b
--- /dev/null
+++ b/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/service/WeatherForecasterService.java
@@ -0,0 +1,20 @@
+package com.baeldung.pattern.hexagonal.service;
+
+import com.baeldung.pattern.hexagonal.repository.WeatherRepository;
+
+public class WeatherForecasterService {
+ private final WeatherRepository repository;
+
+ public WeatherForecasterService(WeatherRepository repository) {
+ this.repository = repository;
+ }
+
+ public double forecast(String location) {
+ String normalizedLocation = getNormalizedLocation(location);
+ return repository.getTemperature(normalizedLocation);
+ }
+
+ private String getNormalizedLocation(String location) {
+ return location == null ? "" : location.toLowerCase();
+ }
+}
diff --git a/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/ui/WeatherForecasterConsoleUI.java b/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/ui/WeatherForecasterConsoleUI.java
new file mode 100644
index 0000000000..3877563694
--- /dev/null
+++ b/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/ui/WeatherForecasterConsoleUI.java
@@ -0,0 +1,48 @@
+package com.baeldung.pattern.hexagonal.ui;
+
+import com.baeldung.pattern.hexagonal.service.WeatherForecasterService;
+
+import java.io.PrintStream;
+import java.nio.charset.StandardCharsets;
+import java.util.Scanner;
+
+public class WeatherForecasterConsoleUI implements WeatherForecasterUI {
+ private WeatherForecasterService service;
+ private Scanner in;
+ private PrintStream out;
+
+ public WeatherForecasterConsoleUI(WeatherForecasterService service) {
+ this.service = service;
+ this.in = new Scanner(System.in);
+ this.out = new PrintStream(System.out, true, StandardCharsets.UTF_8);
+ }
+
+ @Override
+ public void start() {
+ String input = getInput();
+ while (isNotExit(input)) {
+ showTemperature(input);
+ input = getInput();
+ }
+ stop();
+ }
+
+ private String getInput() {
+ out.print("Location: ");
+ return in.nextLine();
+ }
+
+ private boolean isNotExit(String input) {
+ return !input.equalsIgnoreCase("exit");
+ }
+
+ private void showTemperature(String input) {
+ double temperature = service.forecast(input);
+ out.printf("%.2f\u00B0C%n", temperature);
+ }
+
+ private void stop() {
+ in.close();
+ out.close();
+ }
+}
diff --git a/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/ui/WeatherForecasterUI.java b/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/ui/WeatherForecasterUI.java
new file mode 100644
index 0000000000..da25cec7bb
--- /dev/null
+++ b/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/ui/WeatherForecasterUI.java
@@ -0,0 +1,5 @@
+package com.baeldung.pattern.hexagonal.ui;
+
+public interface WeatherForecasterUI {
+ void start();
+}
diff --git a/patterns/pom.xml b/patterns/pom.xml
index 112eecb606..be419ace86 100644
--- a/patterns/pom.xml
+++ b/patterns/pom.xml
@@ -1,5 +1,5 @@
-
4.0.0
patterns
@@ -22,6 +22,7 @@
cqrs-es
front-controller
hexagonal-architecture
+ hexagonal
intercepting-filter
solid
clean-architecture