Java 11 migration: patterns starting with a (#1084)

* Moves abstract-factory pattern to java 11

* Moves abstract-document pattern to java 11

* Moves acyclic-visitor pattern to java 11

* Moves adapter pattern to java 11

* Moves aggregator-microservices pattern to java 11

* Moves api-gateway pattern to java 11
This commit is contained in:
Anurag Agarwal 2019-11-13 21:34:51 +05:30 committed by Ilkka Seppälä
parent 3c57bf7078
commit f04fc3c0dc
26 changed files with 151 additions and 172 deletions

View File

@ -23,10 +23,10 @@
package com.iluwatar.abstractdocument;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Stream;
@ -55,9 +55,13 @@ public abstract class AbstractDocument implements Document {
@Override
public <T> Stream<T> children(String key, Function<Map<String, Object>, T> constructor) {
Optional<List<Map<String, Object>>> any = Stream.of(get(key)).filter(Objects::nonNull)
.map(el -> (List<Map<String, Object>>) el).findAny();
return any.map(maps -> maps.stream().map(constructor)).orElseGet(Stream::empty);
return Stream.ofNullable(get(key))
.filter(Objects::nonNull)
.map(el -> (List<Map<String, Object>>) el)
.findAny()
.stream()
.flatMap(Collection::stream)
.map(constructor);
}
@Override

View File

@ -66,11 +66,14 @@ public class App {
var car = new Car(carProperties);
LOGGER.info("Here is our car:");
LOGGER.info("-> model: {}", car.getModel().get());
LOGGER.info("-> price: {}", car.getPrice().get());
LOGGER.info("-> model: {}", car.getModel().orElseThrow());
LOGGER.info("-> price: {}", car.getPrice().orElseThrow());
LOGGER.info("-> parts: ");
car.getParts().forEach(p -> LOGGER
.info("\t{}/{}/{}", p.getType().get(), p.getModel().get(), p.getPrice().get()));
car.getParts().forEach(p -> LOGGER.info("\t{}/{}/{}",
p.getType().orElse(null),
p.getModel().orElse(null),
p.getPrice().orElse(null))
);
}
/**

View File

@ -23,14 +23,14 @@
package com.iluwatar.abstractdocument;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
/**
* AbstractDocument test class
@ -61,22 +61,22 @@ public class AbstractDocumentTest {
document.put(KEY, children);
Stream<DocumentImplementation> childrenStream = document.children(KEY, DocumentImplementation::new);
var childrenStream = document.children(KEY, DocumentImplementation::new);
assertNotNull(children);
assertEquals(2, childrenStream.count());
}
@Test
public void shouldRetrieveEmptyStreamForNonExistingChildren() {
Stream<DocumentImplementation> children = document.children(KEY, DocumentImplementation::new);
var children = document.children(KEY, DocumentImplementation::new);
assertNotNull(children);
assertEquals(0, children.count());
}
@Test
public void shouldIncludePropsInToString() {
Map<String, Object> props = Map.of(KEY, VALUE);
DocumentImplementation document = new DocumentImplementation(props);
var props = Map.of(KEY, (Object) VALUE);
var document = new DocumentImplementation(props);
assertTrue(document.toString().contains(KEY));
assertTrue(document.toString().contains(VALUE));
}

View File

@ -23,15 +23,14 @@
package com.iluwatar.abstractdocument;
import static org.junit.jupiter.api.Assertions.assertEquals;
import com.iluwatar.abstractdocument.domain.Car;
import com.iluwatar.abstractdocument.domain.Part;
import com.iluwatar.abstractdocument.domain.enums.Property;
import org.junit.jupiter.api.Test;
import java.util.List;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
/**
* Test for Part and Car
@ -47,27 +46,27 @@ public class DomainTest {
@Test
public void shouldConstructPart() {
Map<String, Object> partProperties = Map.of(
Property.TYPE.toString(), TEST_PART_TYPE,
Property.MODEL.toString(), TEST_PART_MODEL,
Property.PRICE.toString(), TEST_PART_PRICE);
Part part = new Part(partProperties);
assertEquals(TEST_PART_TYPE, part.getType().get());
assertEquals(TEST_PART_MODEL, part.getModel().get());
assertEquals(TEST_PART_PRICE, part.getPrice().get());
var partProperties = Map.of(
Property.TYPE.toString(), TEST_PART_TYPE,
Property.MODEL.toString(), TEST_PART_MODEL,
Property.PRICE.toString(), (Object) TEST_PART_PRICE
);
var part = new Part(partProperties);
assertEquals(TEST_PART_TYPE, part.getType().orElseThrow());
assertEquals(TEST_PART_MODEL, part.getModel().orElseThrow());
assertEquals(TEST_PART_PRICE, part.getPrice().orElseThrow());
}
@Test
public void shouldConstructCar() {
Map<String, Object> carProperties = Map.of(
Property.MODEL.toString(), TEST_CAR_MODEL,
Property.PRICE.toString(), TEST_CAR_PRICE,
Property.PARTS.toString(), List.of(Map.of(), Map.of()));
Car car = new Car(carProperties);
assertEquals(TEST_CAR_MODEL, car.getModel().get());
assertEquals(TEST_CAR_PRICE, car.getPrice().get());
var carProperties = Map.of(
Property.MODEL.toString(), TEST_CAR_MODEL,
Property.PRICE.toString(), TEST_CAR_PRICE,
Property.PARTS.toString(), List.of(Map.of(), Map.of())
);
var car = new Car(carProperties);
assertEquals(TEST_CAR_MODEL, car.getModel().orElseThrow());
assertEquals(TEST_CAR_PRICE, car.getPrice().orElseThrow());
assertEquals(2, car.getParts().count());
}

View File

@ -109,10 +109,10 @@ public class OrcKingdomFactory implements KingdomFactory {
Now we have our abstract factory that lets us make family of related objects i.e. Elven kingdom factory creates Elven castle, king and army etc.
```java
KingdomFactory factory = new ElfKingdomFactory();
Castle castle = factory.createCastle();
King king = factory.createKing();
Army army = factory.createArmy();
var factory = new ElfKingdomFactory();
var castle = factory.createCastle();
var king = factory.createKing();
var army = factory.createArmy();
castle.getDescription(); // Output: This is the Elven castle!
king.getDescription(); // Output: This is the Elven king!
@ -143,7 +143,7 @@ public static class FactoryMaker {
}
public static void main(String[] args) {
App app = new App();
var app = new App();
LOGGER.info("Elf Kingdom");
app.createKingdom(FactoryMaker.makeFactory(KingdomType.ELF));

View File

@ -128,7 +128,7 @@ public class App {
*/
public static void main(String[] args) {
App app = new App();
var app = new App();
LOGGER.info("Elf Kingdom");
app.createKingdom(FactoryMaker.makeFactory(KingdomType.ELF));

View File

@ -28,7 +28,6 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
import com.iluwatar.abstractfactory.App.FactoryMaker;
import com.iluwatar.abstractfactory.App.FactoryMaker.KingdomType;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@ -49,30 +48,30 @@ public class AbstractFactoryTest {
@Test
public void king() {
final King elfKing = app.getKing(elfFactory);
final var elfKing = app.getKing(elfFactory);
assertTrue(elfKing instanceof ElfKing);
assertEquals(ElfKing.DESCRIPTION, elfKing.getDescription());
final King orcKing = app.getKing(orcFactory);
final var orcKing = app.getKing(orcFactory);
assertTrue(orcKing instanceof OrcKing);
assertEquals(OrcKing.DESCRIPTION, orcKing.getDescription());
}
@Test
public void castle() {
final Castle elfCastle = app.getCastle(elfFactory);
final var elfCastle = app.getCastle(elfFactory);
assertTrue(elfCastle instanceof ElfCastle);
assertEquals(ElfCastle.DESCRIPTION, elfCastle.getDescription());
final Castle orcCastle = app.getCastle(orcFactory);
final var orcCastle = app.getCastle(orcFactory);
assertTrue(orcCastle instanceof OrcCastle);
assertEquals(OrcCastle.DESCRIPTION, orcCastle.getDescription());
}
@Test
public void army() {
final Army elfArmy = app.getArmy(elfFactory);
final var elfArmy = app.getArmy(elfFactory);
assertTrue(elfArmy instanceof ElfArmy);
assertEquals(ElfArmy.DESCRIPTION, elfArmy.getDescription());
final Army orcArmy = app.getArmy(orcFactory);
final var orcArmy = app.getArmy(orcFactory);
assertTrue(orcArmy instanceof OrcArmy);
assertEquals(OrcArmy.DESCRIPTION, orcArmy.getDescription());
}
@ -80,9 +79,9 @@ public class AbstractFactoryTest {
@Test
public void createElfKingdom() {
app.createKingdom(elfFactory);
final King king = app.getKing();
final Castle castle = app.getCastle();
final Army army = app.getArmy();
final var king = app.getKing();
final var castle = app.getCastle();
final var army = app.getArmy();
assertTrue(king instanceof ElfKing);
assertEquals(ElfKing.DESCRIPTION, king.getDescription());
assertTrue(castle instanceof ElfCastle);
@ -94,9 +93,9 @@ public class AbstractFactoryTest {
@Test
public void createOrcKingdom() {
app.createKingdom(orcFactory);
final King king = app.getKing();
final Castle castle = app.getCastle();
final Army army = app.getArmy();
final var king = app.getKing();
final var castle = app.getCastle();
final var army = app.getArmy();
assertTrue(king instanceof OrcKing);
assertEquals(OrcKing.DESCRIPTION, king.getDescription());
assertTrue(castle instanceof OrcCastle);

View File

@ -25,15 +25,12 @@ package com.iluwatar.abstractfactory;
import org.junit.jupiter.api.Test;
import java.io.IOException;
/**
* Tests that Abstract Factory example runs without errors.
*/
public class AppTest {
@Test
public void test() throws IOException {
String[] args = {};
App.main(args);
public void test() {
App.main(new String[]{});
}
}

View File

@ -25,16 +25,13 @@ package com.iluwatar.acyclicvisitor;
import org.junit.jupiter.api.Test;
import com.iluwatar.acyclicvisitor.App;
/**
* Tests that the Acyclic Visitor example runs without errors.
*/
public class AppTest {
@Test
public void test() {
String[] args = {};
App.main(args);
App.main(new String[]{});
}
}

View File

@ -37,7 +37,7 @@ import uk.org.lidalia.slf4jtest.TestLoggerFactory;
*/
public class ConfigureForDosVisitorTest {
TestLogger logger = TestLoggerFactory.getTestLogger(ConfigureForDosVisitor.class);
private TestLogger logger = TestLoggerFactory.getTestLogger(ConfigureForDosVisitor.class);
@Test
public void testVisitForZoom() {
@ -46,19 +46,21 @@ public class ConfigureForDosVisitorTest {
conDos.visit(zoom);
assertThat(logger.getLoggingEvents()).extracting("level", "message").contains(
tuple(INFO, zoom + " used with Dos configurator."));
assertThat(logger.getLoggingEvents())
.extracting("level", "message")
.contains(tuple(INFO, zoom + " used with Dos configurator."));
}
@Test
public void testVisitForHayes() {
ConfigureForDosVisitor conDos = new ConfigureForDosVisitor();
Hayes hayes = new Hayes();
var conDos = new ConfigureForDosVisitor();
var hayes = new Hayes();
conDos.visit(hayes);
assertThat(logger.getLoggingEvents()).extracting("level", "message").contains(
tuple(INFO, hayes + " used with Dos configurator."));
assertThat(logger.getLoggingEvents())
.extracting("level", "message")
.contains(tuple(INFO, hayes + " used with Dos configurator."));
}
@AfterEach

View File

@ -52,7 +52,8 @@ public class ConfigureForUnixVisitorTest {
conUnix.visit(zoom);
assertThat(LOGGER.getLoggingEvents()).extracting("level", "message").contains(
tuple(INFO, zoom + " used with Unix configurator."));
assertThat(LOGGER.getLoggingEvents())
.extracting("level", "message")
.contains(tuple(INFO, zoom + " used with Unix configurator."));
}
}

View File

@ -93,7 +93,7 @@ public class FishingBoatAdapter implements RowingBoat {
And now the `Captain` can use the `FishingBoat` to escape the pirates.
```java
Captain captain = new Captain(new FishingBoatAdapter());
var captain = new Captain(new FishingBoatAdapter());
captain.row();
```

View File

@ -23,18 +23,16 @@
package com.iluwatar.adapter;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.util.HashMap;
import java.util.Map;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import java.util.HashMap;
import java.util.Map;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
/**
* Test class
*
*/
public class AdapterPatternTest {
@ -51,7 +49,7 @@ public class AdapterPatternTest {
public void setup() {
beans = new HashMap<>();
FishingBoatAdapter fishingBoatAdapter = spy(new FishingBoatAdapter());
var fishingBoatAdapter = spy(new FishingBoatAdapter());
beans.put(FISHING_BEAN, fishingBoatAdapter);
var captain = new Captain();
@ -60,10 +58,10 @@ public class AdapterPatternTest {
}
/**
* This test asserts that when we use the row() method on a captain bean(client), it is
* internally calling sail method on the fishing boat object. The Adapter ({@link FishingBoatAdapter}
* ) converts the interface of the target class ( {@link FishingBoat}) into a suitable one
* expected by the client ({@link Captain} ).
* This test asserts that when we use the row() method on a captain bean(client), it is internally
* calling sail method on the fishing boat object. The Adapter ({@link FishingBoatAdapter} )
* converts the interface of the target class ( {@link FishingBoat}) into a suitable one expected
* by the client ({@link Captain} ).
*/
@Test
public void testAdapter() {

View File

@ -25,15 +25,12 @@ package com.iluwatar.adapter;
import org.junit.jupiter.api.Test;
import java.io.IOException;
/**
* Tests that Adapter example runs without errors.
*/
public class AppTest {
@Test
public void test() throws IOException {
String[] args = {};
App.main(args);
public void test() {
App.main(new String[]{});
}
}

View File

@ -23,6 +23,8 @@
package com.iluwatar.aggregator.microservices;
import static java.util.Objects.requireNonNullElse;
import javax.annotation.Resource;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@ -52,20 +54,14 @@ public class Aggregator {
public Product getProduct() {
var product = new Product();
String productTitle = informationClient.getProductTitle();
Integer productInventory = inventoryClient.getProductInventories();
var productTitle = informationClient.getProductTitle();
var productInventory = inventoryClient.getProductInventories();
if (productTitle != null) {
product.setTitle(productTitle);
} else {
product.setTitle("Error: Fetching Product Title Failed"); //Fallback to error message
}
//Fallback to error message
product.setTitle(requireNonNullElse(productTitle, "Error: Fetching Product Title Failed"));
if (productInventory != null) {
product.setProductInventories(productInventory);
} else {
product.setProductInventories(-1); //Fallback to default error inventory
}
//Fallback to default error inventory
product.setProductInventories(requireNonNullElse(productInventory, -1));
return product;
}

View File

@ -42,19 +42,19 @@ public class ProductInformationClientImpl implements ProductInformationClient {
@Override
public String getProductTitle() {
String response = null;
var request =
HttpRequest.newBuilder().GET().uri(URI.create("http://localhost:51515/information"))
.build();
var request = HttpRequest.newBuilder()
.GET()
.uri(URI.create("http://localhost:51515/information"))
.build();
var client = HttpClient.newHttpClient();
try {
var httpResponse = client.send(request, HttpResponse.BodyHandlers.ofString());
response = httpResponse.body();
return httpResponse.body();
} catch (IOException ioe) {
LOGGER.error("IOException Occurred", ioe);
} catch (InterruptedException ie) {
LOGGER.error("InterruptedException Occurred", ie);
}
return response;
return null;
}
}

View File

@ -44,9 +44,10 @@ public class ProductInventoryClientImpl implements ProductInventoryClient {
public Integer getProductInventories() {
var response = "";
var request =
HttpRequest.newBuilder().GET().uri(URI.create("http://localhost:51516/inventories"))
.build();
var request = HttpRequest.newBuilder()
.GET()
.uri(URI.create("http://localhost:51516/inventories"))
.build();
var client = HttpClient.newHttpClient();
try {
var httpResponse = client.send(request, HttpResponse.BodyHandlers.ofString());

View File

@ -56,13 +56,13 @@ public class AggregatorTest {
*/
@Test
public void testGetProduct() {
String title = "The Product Title.";
int inventories = 5;
var title = "The Product Title.";
var inventories = 5;
when(informationClient.getProductTitle()).thenReturn(title);
when(inventoryClient.getProductInventories()).thenReturn(inventories);
Product testProduct = aggregator.getProduct();
var testProduct = aggregator.getProduct();
assertEquals(title, testProduct.getTitle());
assertEquals(inventories, testProduct.getProductInventories());

View File

@ -34,10 +34,8 @@ public class InformationControllerTest {
@Test
public void shouldGetProductTitle() {
InformationController infoController = new InformationController();
String title = infoController.getProductTitle();
var infoController = new InformationController();
var title = infoController.getProductTitle();
assertEquals("The Product Title.", title);
}

View File

@ -33,10 +33,8 @@ import org.junit.jupiter.api.Test;
public class InventoryControllerTest {
@Test
public void testGetProductInventories() {
InventoryController inventoryController = new InventoryController();
int numberOfInventories = inventoryController.getProductInventories();
var inventoryController = new InventoryController();
var numberOfInventories = inventoryController.getProductInventories();
assertEquals(5, numberOfInventories);
}
}

View File

@ -47,7 +47,7 @@ public class ApiGateway {
*/
@RequestMapping(path = "/desktop", method = RequestMethod.GET)
public DesktopProduct getProductDesktop() {
DesktopProduct desktopProduct = new DesktopProduct();
var desktopProduct = new DesktopProduct();
desktopProduct.setImagePath(imageClient.getImagePath());
desktopProduct.setPrice(priceClient.getPrice());
return desktopProduct;
@ -60,7 +60,7 @@ public class ApiGateway {
*/
@RequestMapping(path = "/mobile", method = RequestMethod.GET)
public MobileProduct getProductMobile() {
MobileProduct mobileProduct = new MobileProduct();
var mobileProduct = new MobileProduct();
mobileProduct.setPrice(priceClient.getPrice());
return mobileProduct;
}

View File

@ -27,7 +27,6 @@ import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.http.HttpResponse.BodyHandlers;
import org.springframework.stereotype.Component;
@ -43,21 +42,19 @@ public class ImageClientImpl implements ImageClient {
*/
@Override
public String getImagePath() {
String response = null;
HttpClient httpClient = HttpClient.newHttpClient();
HttpRequest httpGet =
HttpRequest.newBuilder().GET().uri(URI.create("http://localhost:50005/image-path")).build();
var httpClient = HttpClient.newHttpClient();
var httpGet = HttpRequest.newBuilder()
.GET()
.uri(URI.create("http://localhost:50005/image-path"))
.build();
try {
HttpResponse<String> httpResponse = httpClient.send(httpGet, BodyHandlers.ofString());
response = httpResponse.body();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
var httpResponse = httpClient.send(httpGet, BodyHandlers.ofString());
return httpResponse.body();
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
return response;
return null;
}
}

View File

@ -27,7 +27,6 @@ import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.http.HttpResponse.BodyHandlers;
import org.springframework.stereotype.Component;
@ -43,22 +42,19 @@ public class PriceClientImpl implements PriceClient {
*/
@Override
public String getPrice() {
String response = null;
HttpClient httpClient = HttpClient.newHttpClient();
HttpRequest httpGet =
HttpRequest.newBuilder().GET().uri(URI.create("http://localhost:50006/price")).build();
var httpClient = HttpClient.newHttpClient();
var httpGet = HttpRequest.newBuilder()
.GET()
.uri(URI.create("http://localhost:50006/price"))
.build();
try {
HttpResponse<String> httpResponse = httpClient.send(httpGet, BodyHandlers.ofString());
response = httpResponse.body();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
var httpResponse = httpClient.send(httpGet, BodyHandlers.ofString());
return httpResponse.body();
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
return response;
return null;
}
}

View File

@ -23,15 +23,15 @@
package com.iluwatar.api.gateway;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.when;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.when;
/**
* Test API Gateway Pattern
*/
@ -56,12 +56,12 @@ public class ApiGatewayTest {
*/
@Test
public void testGetProductDesktop() {
String imagePath = "/product-image.png";
String price = "20";
var imagePath = "/product-image.png";
var price = "20";
when(imageClient.getImagePath()).thenReturn(imagePath);
when(priceClient.getPrice()).thenReturn(price);
DesktopProduct desktopProduct = apiGateway.getProductDesktop();
var desktopProduct = apiGateway.getProductDesktop();
assertEquals(price, desktopProduct.getPrice());
assertEquals(imagePath, desktopProduct.getImagePath());
@ -72,10 +72,10 @@ public class ApiGatewayTest {
*/
@Test
public void testGetProductMobile() {
String price = "20";
var price = "20";
when(priceClient.getPrice()).thenReturn(price);
MobileProduct mobileProduct = apiGateway.getProductMobile();
var mobileProduct = apiGateway.getProductMobile();
assertEquals(price, mobileProduct.getPrice());
}

View File

@ -23,20 +23,18 @@
package com.iluwatar.image.microservice;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
/**
* Test for Image Rest Controller
*/
public class ImageControllerTest {
@Test
public void testGetImagePath() {
ImageController imageController = new ImageController();
String imagePath = imageController.getImagePath();
var imageController = new ImageController();
var imagePath = imageController.getImagePath();
assertEquals("/product-image.png", imagePath);
}
}

View File

@ -23,20 +23,18 @@
package com.iluwatar.price.microservice;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
/**
* Test for Price Rest Controller
*/
public class PriceControllerTest {
@Test
public void testgetPrice() {
PriceController priceController = new PriceController();
String price = priceController.getPrice();
var priceController = new PriceController();
var price = priceController.getPrice();
assertEquals("20", price);
}
}