mirror of
https://github.com/tiennm99/java-design-patterns.git
synced 2026-08-21 20:24:23 +00:00
deps: Refactor dependencies (#3224)
* remove spring dep move junit, logging, mockito under dep mgmt * upgrade anti-corruption-layer deps * async method invocation * balking, bloc * bridge to bytecode * caching * callback - cqrs * component - health check * hexagonal - metadata mapping * rest of the patterns * remove checkstyle, take spotless into use
This commit is contained in:
@@ -27,21 +27,21 @@ package com.iluwatar.gateway;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* the Gateway design pattern is a structural design pattern that provides a unified interface to a set of
|
||||
* interfaces in a subsystem. It involves creating a Gateway interface that serves as a common entry point for
|
||||
* interacting with various services, and concrete implementations of this interface for different external services.
|
||||
* the Gateway design pattern is a structural design pattern that provides a unified interface to a
|
||||
* set of interfaces in a subsystem. It involves creating a Gateway interface that serves as a
|
||||
* common entry point for interacting with various services, and concrete implementations of this
|
||||
* interface for different external services.
|
||||
*
|
||||
* <p>In this example, GateFactory is the factory class, and it provides a method to create different kinds of external
|
||||
* services. ExternalServiceA, B, and C are virtual implementations of the external services. Each service provides its
|
||||
* own implementation of the execute() method. The Gateway interface is the common interface for all external services.
|
||||
* The App class serves as the main entry point for the application implementing the Gateway design pattern. Through
|
||||
* the Gateway interface, the App class could call each service with much less complexity.
|
||||
* <p>In this example, GateFactory is the factory class, and it provides a method to create
|
||||
* different kinds of external services. ExternalServiceA, B, and C are virtual implementations of
|
||||
* the external services. Each service provides its own implementation of the execute() method. The
|
||||
* Gateway interface is the common interface for all external services. The App class serves as the
|
||||
* main entry point for the application implementing the Gateway design pattern. Through the Gateway
|
||||
* interface, the App class could call each service with much less complexity.
|
||||
*/
|
||||
@Slf4j
|
||||
public class App {
|
||||
/**
|
||||
* Simulate an application calling external services.
|
||||
*/
|
||||
/** Simulate an application calling external services. */
|
||||
public static void main(String[] args) throws Exception {
|
||||
GatewayFactory gatewayFactory = new GatewayFactory();
|
||||
|
||||
|
||||
@@ -24,12 +24,9 @@
|
||||
*/
|
||||
package com.iluwatar.gateway;
|
||||
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* ExternalServiceA is one of external services.
|
||||
*/
|
||||
/** ExternalServiceA is one of external services. */
|
||||
@Slf4j
|
||||
class ExternalServiceA implements Gateway {
|
||||
@Override
|
||||
|
||||
@@ -24,12 +24,9 @@
|
||||
*/
|
||||
package com.iluwatar.gateway;
|
||||
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* ExternalServiceB is one of external services.
|
||||
*/
|
||||
/** ExternalServiceB is one of external services. */
|
||||
@Slf4j
|
||||
class ExternalServiceB implements Gateway {
|
||||
@Override
|
||||
@@ -39,4 +36,3 @@ class ExternalServiceB implements Gateway {
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,12 +24,9 @@
|
||||
*/
|
||||
package com.iluwatar.gateway;
|
||||
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* ExternalServiceC is one of external services.
|
||||
*/
|
||||
/** ExternalServiceC is one of external services. */
|
||||
@Slf4j
|
||||
class ExternalServiceC implements Gateway {
|
||||
@Override
|
||||
|
||||
@@ -24,9 +24,7 @@
|
||||
*/
|
||||
package com.iluwatar.gateway;
|
||||
|
||||
/**
|
||||
* Service interface.
|
||||
*/
|
||||
/** Service interface. */
|
||||
interface Gateway {
|
||||
void execute() throws Exception;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,8 +28,9 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* The "GatewayFactory" class is responsible for providing different external services in this Gateway design pattern
|
||||
* example. It allows clients to register and retrieve specific gateways based on unique keys.
|
||||
* The "GatewayFactory" class is responsible for providing different external services in this
|
||||
* Gateway design pattern example. It allows clients to register and retrieve specific gateways
|
||||
* based on unique keys.
|
||||
*/
|
||||
public class GatewayFactory {
|
||||
private Map<String, Gateway> gateways = new HashMap<>();
|
||||
|
||||
@@ -24,86 +24,88 @@
|
||||
*/
|
||||
package com.iluwatar.gateway;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
import java.util.concurrent.*;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class AppTest {
|
||||
private GatewayFactory gatewayFactory;
|
||||
private ExecutorService executorService;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
gatewayFactory = new GatewayFactory();
|
||||
executorService = Executors.newFixedThreadPool(2);
|
||||
gatewayFactory.registerGateway("ServiceA", new ExternalServiceA());
|
||||
gatewayFactory.registerGateway("ServiceB", new ExternalServiceB());
|
||||
gatewayFactory.registerGateway("ServiceC", new ExternalServiceC());
|
||||
}
|
||||
private GatewayFactory gatewayFactory;
|
||||
private ExecutorService executorService;
|
||||
|
||||
@Test
|
||||
public void testServiceAExecution() throws InterruptedException, ExecutionException {
|
||||
// Test Service A execution
|
||||
Future<?> serviceAFuture = executorService.submit(() -> {
|
||||
try {
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
gatewayFactory = new GatewayFactory();
|
||||
executorService = Executors.newFixedThreadPool(2);
|
||||
gatewayFactory.registerGateway("ServiceA", new ExternalServiceA());
|
||||
gatewayFactory.registerGateway("ServiceB", new ExternalServiceB());
|
||||
gatewayFactory.registerGateway("ServiceC", new ExternalServiceC());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testServiceAExecution() throws InterruptedException, ExecutionException {
|
||||
// Test Service A execution
|
||||
Future<?> serviceAFuture =
|
||||
executorService.submit(
|
||||
() -> {
|
||||
try {
|
||||
Gateway serviceA = gatewayFactory.getGateway("ServiceA");
|
||||
serviceA.execute();
|
||||
} catch (Exception e) {
|
||||
} catch (Exception e) {
|
||||
fail("Service A should not throw an exception.");
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Wait for Service A to complete
|
||||
serviceAFuture.get();
|
||||
}
|
||||
// Wait for Service A to complete
|
||||
serviceAFuture.get();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServiceCExecutionWithException() throws InterruptedException, ExecutionException {
|
||||
// Test Service B execution with an exception
|
||||
Future<?> serviceBFuture = executorService.submit(() -> {
|
||||
try {
|
||||
@Test
|
||||
void testServiceCExecutionWithException() throws InterruptedException, ExecutionException {
|
||||
// Test Service B execution with an exception
|
||||
Future<?> serviceBFuture =
|
||||
executorService.submit(
|
||||
() -> {
|
||||
try {
|
||||
Gateway serviceB = gatewayFactory.getGateway("ServiceB");
|
||||
serviceB.execute();
|
||||
} catch (Exception e) {
|
||||
} catch (Exception e) {
|
||||
fail("Service B should not throw an exception.");
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Wait for Service B to complete
|
||||
serviceBFuture.get();
|
||||
}
|
||||
// Wait for Service B to complete
|
||||
serviceBFuture.get();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServiceCExecution() throws InterruptedException, ExecutionException {
|
||||
// Test Service C execution
|
||||
Future<?> serviceCFuture = executorService.submit(() -> {
|
||||
try {
|
||||
@Test
|
||||
void testServiceCExecution() throws InterruptedException, ExecutionException {
|
||||
// Test Service C execution
|
||||
Future<?> serviceCFuture =
|
||||
executorService.submit(
|
||||
() -> {
|
||||
try {
|
||||
Gateway serviceC = gatewayFactory.getGateway("ServiceC");
|
||||
serviceC.execute();
|
||||
} catch (Exception e) {
|
||||
} catch (Exception e) {
|
||||
fail("Service C should not throw an exception.");
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Wait for Service C to complete
|
||||
serviceCFuture.get();
|
||||
}
|
||||
// Wait for Service C to complete
|
||||
serviceCFuture.get();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServiceCError() {
|
||||
try {
|
||||
ExternalServiceC serviceC = (ExternalServiceC) gatewayFactory.getGateway("ServiceC");
|
||||
serviceC.error();
|
||||
fail("Service C should throw an exception.");
|
||||
} catch (Exception e) {
|
||||
assertEquals("Service C encountered an error", e.getMessage());
|
||||
}
|
||||
@Test
|
||||
void testServiceCError() {
|
||||
try {
|
||||
ExternalServiceC serviceC = (ExternalServiceC) gatewayFactory.getGateway("ServiceC");
|
||||
serviceC.error();
|
||||
fail("Service C should throw an exception.");
|
||||
} catch (Exception e) {
|
||||
assertEquals("Service C encountered an error", e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,70 +24,69 @@
|
||||
*/
|
||||
package com.iluwatar.gateway;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class ServiceFactoryTest {
|
||||
private GatewayFactory gatewayFactory;
|
||||
private ExecutorService executorService;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
gatewayFactory = new GatewayFactory();
|
||||
executorService = Executors.newFixedThreadPool(2);
|
||||
gatewayFactory.registerGateway("ServiceA", new ExternalServiceA());
|
||||
gatewayFactory.registerGateway("ServiceB", new ExternalServiceB());
|
||||
gatewayFactory.registerGateway("ServiceC", new ExternalServiceC());
|
||||
private GatewayFactory gatewayFactory;
|
||||
private ExecutorService executorService;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
gatewayFactory = new GatewayFactory();
|
||||
executorService = Executors.newFixedThreadPool(2);
|
||||
gatewayFactory.registerGateway("ServiceA", new ExternalServiceA());
|
||||
gatewayFactory.registerGateway("ServiceB", new ExternalServiceB());
|
||||
gatewayFactory.registerGateway("ServiceC", new ExternalServiceC());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGatewayFactoryRegistrationAndRetrieval() {
|
||||
Gateway serviceA = gatewayFactory.getGateway("ServiceA");
|
||||
Gateway serviceB = gatewayFactory.getGateway("ServiceB");
|
||||
Gateway serviceC = gatewayFactory.getGateway("ServiceC");
|
||||
|
||||
// Check if the retrieved instances match their expected types
|
||||
assertTrue(
|
||||
serviceA instanceof ExternalServiceA, "ServiceA should be an instance of ExternalServiceA");
|
||||
assertTrue(
|
||||
serviceB instanceof ExternalServiceB, "ServiceB should be an instance of ExternalServiceB");
|
||||
assertTrue(
|
||||
serviceC instanceof ExternalServiceC, "ServiceC should be an instance of ExternalServiceC");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGatewayFactoryRegistrationWithNonExistingKey() {
|
||||
Gateway nonExistingService = gatewayFactory.getGateway("NonExistingService");
|
||||
assertNull(nonExistingService);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGatewayFactoryConcurrency() throws InterruptedException {
|
||||
int numThreads = 10;
|
||||
CountDownLatch latch = new CountDownLatch(numThreads);
|
||||
AtomicBoolean failed = new AtomicBoolean(false);
|
||||
|
||||
for (int i = 0; i < numThreads; i++) {
|
||||
executorService.submit(
|
||||
() -> {
|
||||
try {
|
||||
Gateway serviceA = gatewayFactory.getGateway("ServiceA");
|
||||
serviceA.execute();
|
||||
} catch (Exception e) {
|
||||
failed.set(true);
|
||||
} finally {
|
||||
latch.countDown();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGatewayFactoryRegistrationAndRetrieval() {
|
||||
Gateway serviceA = gatewayFactory.getGateway("ServiceA");
|
||||
Gateway serviceB = gatewayFactory.getGateway("ServiceB");
|
||||
Gateway serviceC = gatewayFactory.getGateway("ServiceC");
|
||||
|
||||
// Check if the retrieved instances match their expected types
|
||||
assertTrue("ServiceA should be an instance of ExternalServiceA", serviceA instanceof ExternalServiceA);
|
||||
assertTrue("ServiceB should be an instance of ExternalServiceB", serviceB instanceof ExternalServiceB);
|
||||
assertTrue("ServiceC should be an instance of ExternalServiceC", serviceC instanceof ExternalServiceC);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGatewayFactoryRegistrationWithNonExistingKey() {
|
||||
Gateway nonExistingService = gatewayFactory.getGateway("NonExistingService");
|
||||
assertNull(nonExistingService);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGatewayFactoryConcurrency() throws InterruptedException {
|
||||
int numThreads = 10;
|
||||
CountDownLatch latch = new CountDownLatch(numThreads);
|
||||
AtomicBoolean failed = new AtomicBoolean(false);
|
||||
|
||||
for (int i = 0; i < numThreads; i++) {
|
||||
executorService.submit(() -> {
|
||||
try {
|
||||
Gateway serviceA = gatewayFactory.getGateway("ServiceA");
|
||||
serviceA.execute();
|
||||
} catch (Exception e) {
|
||||
failed.set(true);
|
||||
} finally {
|
||||
latch.countDown();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
latch.await();
|
||||
assertFalse("This should not fail", failed.get());
|
||||
}
|
||||
latch.await();
|
||||
assertFalse(failed.get(), "This should not fail");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user