Skip to content

Commit 2d54709

Browse files
FinnS-FFinn
andauthored
feature: Add gateway pattern (iluwatar#1297) (iluwatar#2734)
* Implement Gateway pattern * Fixed docstrings * Fixed README.md * Fixed App * Fixed pom.xml * Fixed pom.xml * Fixed pom.xml * Fixed pom.xml * fixed checkstyle errors and directory names * fixed pom.xml * fixed checkstyle errors * Bug fixed * Bug fixed * Bug fixed * Bug fixed and code improvement * Bug fixed and code improvement * Bug fixed and update README.md * update APP.java * update gateway pattern * Revert "update gateway pattern" This reverts commit f31a00c. * update gateway pattern --------- Co-authored-by: Finn <[email protected]>
1 parent ec80239 commit 2d54709

File tree

12 files changed

+642
-0
lines changed

12 files changed

+642
-0
lines changed

gateway/README.md

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
---
2+
title: Gateway
3+
category: Structural
4+
language: en
5+
tag:
6+
- Gang of Four
7+
- Decoupling
8+
9+
---
10+
11+
## Intent
12+
13+
Provide a interface to access a set of external systems or functionalities. Gateway provides a simple uniform view of
14+
external resources to the internals of an application.
15+
16+
## Explanation
17+
18+
Real-world example
19+
20+
> Gateway acts like a real front gate of a certain city. The people inside the city are called
21+
> internal system, and different outside cities are called external services. The gateway is here
22+
> to provide access for internal system to different external services.
23+
24+
In plain words
25+
26+
> Gateway can provide an interface which lets internal system to utilize external service.
27+
28+
Wikipedia says
29+
30+
> A server that acts as an API front-end, receives API requests, enforces throttling and security
31+
> policies, passes requests to the back-end service and then passes the response back to the requester.
32+
33+
**Programmatic Example**
34+
35+
The main class in our example is the `ExternalService` that contains items.
36+
37+
```java
38+
class ExternalServiceA implements Gateway {
39+
@Override
40+
public void execute() throws Exception {
41+
System.out.println("Executing Service A");
42+
// Simulate a time-consuming task
43+
Thread.sleep(1000);
44+
}
45+
}
46+
47+
/**
48+
* ExternalServiceB is one of external services.
49+
*/
50+
class ExternalServiceB implements Gateway {
51+
@Override
52+
public void execute() throws Exception {
53+
System.out.println("Executing Service B");
54+
// Simulate a time-consuming task
55+
Thread.sleep(1000);
56+
}
57+
}
58+
59+
/**
60+
* ExternalServiceC is one of external services.
61+
*/
62+
class ExternalServiceC implements Gateway {
63+
@Override
64+
public void execute() throws Exception {
65+
System.out.println("Executing Service C");
66+
// Simulate a time-consuming task
67+
Thread.sleep(1000);
68+
}
69+
70+
public void error() throws Exception {
71+
// Simulate an exception
72+
throw new RuntimeException("Service C encountered an error");
73+
}
74+
}
75+
```
76+
77+
To operate these external services, Here's the `App` class:
78+
79+
```java
80+
public class App {
81+
/**
82+
* Simulate an application calling external services.
83+
*/
84+
public static void main(String[] args) throws Exception {
85+
GatewayFactory gatewayFactory = new GatewayFactory();
86+
87+
// Register different gateways
88+
gatewayFactory.registerGateway("ServiceA", new ExternalServiceA());
89+
gatewayFactory.registerGateway("ServiceB", new ExternalServiceB());
90+
gatewayFactory.registerGateway("ServiceC", new ExternalServiceC());
91+
92+
// Use an executor service for asynchronous execution
93+
Gateway serviceA = gatewayFactory.getGateway("ServiceA");
94+
Gateway serviceB = gatewayFactory.getGateway("ServiceB");
95+
Gateway serviceC = gatewayFactory.getGateway("ServiceC");
96+
97+
// Execute external services
98+
try {
99+
serviceA.execute();
100+
serviceB.execute();
101+
serviceC.execute();
102+
} catch (ThreadDeath e) {
103+
System.out.println("Interrupted!" + e);
104+
throw e;
105+
}
106+
}
107+
}
108+
```
109+
110+
The `Gateway` interface is extremely simple.
111+
112+
```java
113+
interface Gateway {
114+
void execute() throws Exception;
115+
}
116+
```
117+
118+
Program output:
119+
120+
```java
121+
Executing Service A
122+
Executing Service B
123+
Executing Service C
124+
```
125+
126+
## Class diagram
127+
128+
![alt text](./etc/gateway.urm.png "gateway")
129+
130+
## Applicability
131+
132+
Use the Gateway pattern
133+
134+
* To access an aggregate object's contents without exposing its internal representation.
135+
* To integration with multiple external services or APIs.
136+
* To provide a uniform interface for traversing different aggregate structures.
137+
138+
## Tutorials
139+
140+
* [Pattern: API Gateway / Backends for Frontends](https://microservices.io/patterns/apigateway.html)
141+
142+
## Known uses
143+
144+
* [API Gateway](https://java-design-patterns.com/patterns/api-gateway/)
145+
* [10 most common use cases of an API Gateway](https://apisix.apache.org/blog/2022/10/27/ten-use-cases-api-gateway/)
146+
147+
## Credits
148+
149+
* [Gateway](https://martinfowler.com/articles/gateway-pattern.html)
150+
* [What is the difference between Facade and Gateway design patterns?](https://stackoverflow.com/questions/4422211/what-is-the-difference-between-facade-and-gateway-design-patterns)

gateway/etc/gateway.urm.png

45.2 KB
Loading

gateway/etc/gateway.urm.puml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
@startuml GatewayPattern
2+
package com.iluwatar.gateway{
3+
class App {
4+
+main(args: String[]): void
5+
}
6+
7+
class GatewayFactory {
8+
-gateways: Map<String, Gateway>
9+
+registerGateway(key: String, gateway: Gateway): void
10+
+getGateway(key: String): Gateway
11+
}
12+
13+
interface Gateway {
14+
{abstract} +execute(): void
15+
}
16+
17+
class ExternalServiceA {
18+
+execute(): void
19+
}
20+
21+
class ExternalServiceB {
22+
+execute(): void
23+
}
24+
25+
class ExternalServiceC {
26+
+execute(): void
27+
+error(): void
28+
}
29+
30+
App --> GatewayFactory : Uses
31+
32+
33+
GatewayFactory --> Gateway : Creates
34+
35+
GatewayFactory --> ExternalServiceA : Registers
36+
GatewayFactory --> ExternalServiceB : Registers
37+
GatewayFactory --> ExternalServiceC : Registers
38+
39+
ExternalServiceA --> Gateway : Implements
40+
ExternalServiceB --> Gateway : Implements
41+
ExternalServiceC --> Gateway : Implements
42+
43+
@enduml

gateway/pom.xml

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
4+
This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
5+
6+
The MIT License
7+
Copyright © 2014-2022 Ilkka Seppälä
8+
9+
Permission is hereby granted, free of charge, to any person obtaining a copy
10+
of this software and associated documentation files (the "Software"), to deal
11+
in the Software without restriction, including without limitation the rights
12+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+
copies of the Software, and to permit persons to whom the Software is
14+
furnished to do so, subject to the following conditions:
15+
16+
The above copyright notice and this permission notice shall be included in
17+
all copies or substantial portions of the Software.
18+
19+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
THE SOFTWARE.
26+
27+
-->
28+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
29+
<modelVersion>4.0.0</modelVersion>
30+
<parent>
31+
<groupId>com.iluwatar</groupId>
32+
<artifactId>java-design-patterns</artifactId>
33+
<version>1.26.0-SNAPSHOT</version>
34+
</parent>
35+
<packaging>jar</packaging>
36+
<artifactId>gateway</artifactId>
37+
<dependencies>
38+
<dependency>
39+
<groupId>org.junit.jupiter</groupId>
40+
<artifactId>junit-jupiter-engine</artifactId>
41+
<scope>test</scope>
42+
</dependency>
43+
<dependency>
44+
<groupId>junit</groupId>
45+
<artifactId>junit</artifactId>
46+
<scope>test</scope>
47+
</dependency>
48+
</dependencies>
49+
<build>
50+
<plugins>
51+
<plugin>
52+
<groupId>org.apache.maven.plugins</groupId>
53+
<artifactId>maven-assembly-plugin</artifactId>
54+
<executions>
55+
<execution>
56+
<configuration>
57+
<archive>
58+
<manifest>
59+
<mainClass>com.iluwatar.gateway.App</mainClass>
60+
</manifest>
61+
</archive>
62+
</configuration>
63+
</execution>
64+
</executions>
65+
</plugin>
66+
</plugins>
67+
</build>
68+
</project>
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
3+
*
4+
* The MIT License
5+
* Copyright © 2014-2022 Ilkka Seppälä
6+
*
7+
* Permission is hereby granted, free of charge, to any person obtaining a copy
8+
* of this software and associated documentation files (the "Software"), to deal
9+
* in the Software without restriction, including without limitation the rights
10+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
* copies of the Software, and to permit persons to whom the Software is
12+
* furnished to do so, subject to the following conditions:
13+
*
14+
* The above copyright notice and this permission notice shall be included in
15+
* all copies or substantial portions of the Software.
16+
*
17+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+
* THE SOFTWARE.
24+
*/
25+
package com.iluwatar.gateway;
26+
27+
import lombok.extern.slf4j.Slf4j;
28+
29+
/**
30+
* the Gateway design pattern is a structural design pattern that provides a unified interface to a set of
31+
* interfaces in a subsystem. It involves creating a Gateway interface that serves as a common entry point for
32+
* interacting with various services, and concrete implementations of this interface for different external services.
33+
*
34+
* <p>In this example, GateFactory is the factory class, and it provides a method to create different kinds of external
35+
* services. ExternalServiceA, B, and C are virtual implementations of the external services. Each service provides its
36+
* own implementation of the execute() method. The Gateway interface is the common interface for all external services.
37+
* The App class serves as the main entry point for the application implementing the Gateway design pattern. Through
38+
* the Gateway interface, the App class could call each service with much less complexity.
39+
*/
40+
@Slf4j
41+
public class App {
42+
/**
43+
* Simulate an application calling external services.
44+
*/
45+
public static void main(String[] args) throws Exception {
46+
GatewayFactory gatewayFactory = new GatewayFactory();
47+
48+
// Register different gateways
49+
gatewayFactory.registerGateway("ServiceA", new ExternalServiceA());
50+
gatewayFactory.registerGateway("ServiceB", new ExternalServiceB());
51+
gatewayFactory.registerGateway("ServiceC", new ExternalServiceC());
52+
53+
// Use an executor service for execution
54+
Gateway serviceA = gatewayFactory.getGateway("ServiceA");
55+
Gateway serviceB = gatewayFactory.getGateway("ServiceB");
56+
Gateway serviceC = gatewayFactory.getGateway("ServiceC");
57+
58+
// Execute external services
59+
try {
60+
serviceA.execute();
61+
serviceB.execute();
62+
serviceC.execute();
63+
} catch (ThreadDeath e) {
64+
LOGGER.info("Interrupted!" + e);
65+
throw e;
66+
}
67+
}
68+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
3+
*
4+
* The MIT License
5+
* Copyright © 2014-2022 Ilkka Seppälä
6+
*
7+
* Permission is hereby granted, free of charge, to any person obtaining a copy
8+
* of this software and associated documentation files (the "Software"), to deal
9+
* in the Software without restriction, including without limitation the rights
10+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
* copies of the Software, and to permit persons to whom the Software is
12+
* furnished to do so, subject to the following conditions:
13+
*
14+
* The above copyright notice and this permission notice shall be included in
15+
* all copies or substantial portions of the Software.
16+
*
17+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+
* THE SOFTWARE.
24+
*/
25+
package com.iluwatar.gateway;
26+
27+
28+
import lombok.extern.slf4j.Slf4j;
29+
import org.slf4j.Logger;
30+
31+
/**
32+
* ExternalServiceA is one of external services.
33+
*/
34+
@Slf4j
35+
class ExternalServiceA implements Gateway {
36+
@Override
37+
public void execute() throws Exception {
38+
LOGGER.info("Executing Service A");
39+
// Simulate a time-consuming task
40+
Thread.sleep(1000);
41+
}
42+
}
43+

0 commit comments

Comments
 (0)