mirror of
https://github.com/tiennm99/java-design-patterns.git
synced 2026-10-13 02:14:45 +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:
1 parent
371439aeaa
commit
0ca162a55c
1863 files changed
+14403
-17632
No files matched your search
@@ -25,8 +25,5 @@
|
||||
|
||||
package com.iluwatar.collectionpipeline;
|
||||
|
||||
/**
|
||||
* A Car class that has the properties of make, model, year and category.
|
||||
*/
|
||||
public record Car(String make, String model, int year, Category category) {
|
||||
}
|
||||
/** A Car class that has the properties of make, model, year and category. */
|
||||
public record Car(String make, String model, int year, Category category) {}
|
||||
@@ -26,12 +26,9 @@ package com.iluwatar.collectionpipeline;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A factory class to create a collection of {@link Car} instances.
|
||||
*/
|
||||
/** A factory class to create a collection of {@link Car} instances. */
|
||||
public class CarFactory {
|
||||
private CarFactory() {
|
||||
}
|
||||
private CarFactory() {}
|
||||
|
||||
/**
|
||||
* Factory method to create a {@link List} of {@link Car} instances.
|
||||
@@ -39,11 +36,12 @@ public class CarFactory {
|
||||
* @return {@link List} of {@link Car}
|
||||
*/
|
||||
public static List<Car> createCars() {
|
||||
return List.of(new Car("Jeep", "Wrangler", 2011, Category.JEEP),
|
||||
return List.of(
|
||||
new Car("Jeep", "Wrangler", 2011, Category.JEEP),
|
||||
new Car("Jeep", "Comanche", 1990, Category.JEEP),
|
||||
new Car("Dodge", "Avenger", 2010, Category.SEDAN),
|
||||
new Car("Buick", "Cascada", 2016, Category.CONVERTIBLE),
|
||||
new Car("Ford", "Focus", 2012, Category.SEDAN),
|
||||
new Car("Chevrolet", "Geo Metro", 1992, Category.CONVERTIBLE));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,9 +24,7 @@
|
||||
*/
|
||||
package com.iluwatar.collectionpipeline;
|
||||
|
||||
/**
|
||||
* Enum for the category of car.
|
||||
*/
|
||||
/** Enum for the category of car. */
|
||||
public enum Category {
|
||||
JEEP,
|
||||
SEDAN,
|
||||
|
||||
+20
-15
@@ -33,20 +33,19 @@ import java.util.stream.Collectors;
|
||||
/**
|
||||
* Iterating and sorting with a collection pipeline
|
||||
*
|
||||
* <p>In functional programming, it's common to sequence complex operations through
|
||||
* a series of smaller modular functions or operations. The series is called a composition of
|
||||
* functions, or a function composition. When a collection of data flows through a function
|
||||
* composition, it becomes a collection pipeline. Function Composition and Collection Pipeline are
|
||||
* two design patterns frequently used in functional-style programming.
|
||||
* <p>In functional programming, it's common to sequence complex operations through a series of
|
||||
* smaller modular functions or operations. The series is called a composition of functions, or a
|
||||
* function composition. When a collection of data flows through a function composition, it becomes
|
||||
* a collection pipeline. Function Composition and Collection Pipeline are two design patterns
|
||||
* frequently used in functional-style programming.
|
||||
*
|
||||
* <p>Instead of passing a lambda expression to the map method, we passed the
|
||||
* method reference Car::getModel. Likewise, instead of passing the lambda expression car ->
|
||||
* car.getYear() to the comparing method, we passed the method reference Car::getYear. Method
|
||||
* references are short, concise, and expressive. It is best to use them wherever possible.
|
||||
* <p>Instead of passing a lambda expression to the map method, we passed the method reference
|
||||
* Car::getModel. Likewise, instead of passing the lambda expression car -> car.getYear() to the
|
||||
* comparing method, we passed the method reference Car::getYear. Method references are short,
|
||||
* concise, and expressive. It is best to use them wherever possible.
|
||||
*/
|
||||
public class FunctionalProgramming {
|
||||
private FunctionalProgramming() {
|
||||
}
|
||||
private FunctionalProgramming() {}
|
||||
|
||||
/**
|
||||
* Method to get models using for collection pipeline.
|
||||
@@ -55,8 +54,11 @@ public class FunctionalProgramming {
|
||||
* @return {@link List} of {@link String} representing models built after year 2000
|
||||
*/
|
||||
public static List<String> getModelsAfter2000(List<Car> cars) {
|
||||
return cars.stream().filter(car -> car.year() > 2000).sorted(Comparator.comparing(Car::year))
|
||||
.map(Car::model).toList();
|
||||
return cars.stream()
|
||||
.filter(car -> car.year() > 2000)
|
||||
.sorted(Comparator.comparing(Car::year))
|
||||
.map(Car::model)
|
||||
.toList();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -76,8 +78,11 @@ public class FunctionalProgramming {
|
||||
* @return {@link List} of {@link Car} to belonging to the group
|
||||
*/
|
||||
public static List<Car> getSedanCarsOwnedSortedByDate(List<Person> persons) {
|
||||
return persons.stream().map(Person::cars).flatMap(List::stream)
|
||||
return persons.stream()
|
||||
.map(Person::cars)
|
||||
.flatMap(List::stream)
|
||||
.filter(car -> Category.SEDAN.equals(car.category()))
|
||||
.sorted(Comparator.comparing(Car::year)).toList();
|
||||
.sorted(Comparator.comparing(Car::year))
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
+26
-24
@@ -35,21 +35,20 @@ import java.util.Map;
|
||||
* Imperative-style programming to iterate over the list and get the names of cars made later than
|
||||
* the year 2000. We then sort the models in ascending order by year.
|
||||
*
|
||||
* <p>As you can see, there's a lot of looping in this code. First, the
|
||||
* getModelsAfter2000UsingFor method takes a list of cars as its parameter. It extracts or filters
|
||||
* out cars made after the year 2000, putting them into a new list named carsSortedByYear. Next, it
|
||||
* sorts that list in ascending order by year-of-make. Finally, it loops through the list
|
||||
* carsSortedByYear to get the model names and returns them in a list.
|
||||
* <p>As you can see, there's a lot of looping in this code. First, the getModelsAfter2000UsingFor
|
||||
* method takes a list of cars as its parameter. It extracts or filters out cars made after the year
|
||||
* 2000, putting them into a new list named carsSortedByYear. Next, it sorts that list in ascending
|
||||
* order by year-of-make. Finally, it loops through the list carsSortedByYear to get the model names
|
||||
* and returns them in a list.
|
||||
*
|
||||
* <p>This short example demonstrates what I call the effect of statements. While
|
||||
* functions and methods in general can be used as expressions, the {@link Collections} sort method
|
||||
* doesn't return a result. Because it is used as a statement, it mutates the list given as
|
||||
* argument. Both of the for loops also mutate lists as they iterate. Being statements, that's just
|
||||
* how these elements work. As a result, the code contains unnecessary garbage variables
|
||||
* <p>This short example demonstrates what I call the effect of statements. While functions and
|
||||
* methods in general can be used as expressions, the {@link Collections} sort method doesn't return
|
||||
* a result. Because it is used as a statement, it mutates the list given as argument. Both of the
|
||||
* for loops also mutate lists as they iterate. Being statements, that's just how these elements
|
||||
* work. As a result, the code contains unnecessary garbage variables
|
||||
*/
|
||||
public class ImperativeProgramming {
|
||||
private ImperativeProgramming() {
|
||||
}
|
||||
private ImperativeProgramming() {}
|
||||
|
||||
/**
|
||||
* Method to return the car models built after year 2000 using for loops.
|
||||
@@ -66,12 +65,14 @@ public class ImperativeProgramming {
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort(carsSortedByYear, new Comparator<Car>() {
|
||||
@Override
|
||||
public int compare(Car car1, Car car2) {
|
||||
return car1.year() - car2.year();
|
||||
}
|
||||
});
|
||||
Collections.sort(
|
||||
carsSortedByYear,
|
||||
new Comparator<Car>() {
|
||||
@Override
|
||||
public int compare(Car car1, Car car2) {
|
||||
return car1.year() - car2.year();
|
||||
}
|
||||
});
|
||||
|
||||
List<String> models = new ArrayList<>();
|
||||
for (Car car : carsSortedByYear) {
|
||||
@@ -121,12 +122,13 @@ public class ImperativeProgramming {
|
||||
}
|
||||
}
|
||||
|
||||
sedanCars.sort(new Comparator<Car>() {
|
||||
@Override
|
||||
public int compare(Car o1, Car o2) {
|
||||
return o1.year() - o2.year();
|
||||
}
|
||||
});
|
||||
sedanCars.sort(
|
||||
new Comparator<Car>() {
|
||||
@Override
|
||||
public int compare(Car o1, Car o2) {
|
||||
return o1.year() - o2.year();
|
||||
}
|
||||
});
|
||||
|
||||
return sedanCars;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,5 @@ package com.iluwatar.collectionpipeline;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A Person class that has the list of cars that the person owns and use.
|
||||
*/
|
||||
/** A Person class that has the list of cars that the person owns and use. */
|
||||
public record Person(List<Car> cars) {}
|
||||
@@ -31,9 +31,7 @@ import java.util.Map;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Tests that Collection Pipeline methods work as expected.
|
||||
*/
|
||||
/** Tests that Collection Pipeline methods work as expected. */
|
||||
@Slf4j
|
||||
class AppTest {
|
||||
|
||||
@@ -53,19 +51,20 @@ class AppTest {
|
||||
|
||||
@Test
|
||||
void testGetGroupingOfCarsByCategory() {
|
||||
var modelsExpected = Map.of(
|
||||
Category.CONVERTIBLE, List.of(
|
||||
new Car("Buick", "Cascada", 2016, Category.CONVERTIBLE),
|
||||
new Car("Chevrolet", "Geo Metro", 1992, Category.CONVERTIBLE)
|
||||
),
|
||||
Category.SEDAN, List.of(
|
||||
new Car("Dodge", "Avenger", 2010, Category.SEDAN),
|
||||
new Car("Ford", "Focus", 2012, Category.SEDAN)
|
||||
),
|
||||
Category.JEEP, List.of(
|
||||
new Car("Jeep", "Wrangler", 2011, Category.JEEP),
|
||||
new Car("Jeep", "Comanche", 1990, Category.JEEP))
|
||||
);
|
||||
var modelsExpected =
|
||||
Map.of(
|
||||
Category.CONVERTIBLE,
|
||||
List.of(
|
||||
new Car("Buick", "Cascada", 2016, Category.CONVERTIBLE),
|
||||
new Car("Chevrolet", "Geo Metro", 1992, Category.CONVERTIBLE)),
|
||||
Category.SEDAN,
|
||||
List.of(
|
||||
new Car("Dodge", "Avenger", 2010, Category.SEDAN),
|
||||
new Car("Ford", "Focus", 2012, Category.SEDAN)),
|
||||
Category.JEEP,
|
||||
List.of(
|
||||
new Car("Jeep", "Wrangler", 2011, Category.JEEP),
|
||||
new Car("Jeep", "Comanche", 1990, Category.JEEP)));
|
||||
var modelsFunctional = FunctionalProgramming.getGroupingOfCarsByCategory(cars);
|
||||
var modelsImperative = ImperativeProgramming.getGroupingOfCarsByCategory(cars);
|
||||
LOGGER.info("Category " + modelsFunctional);
|
||||
@@ -76,10 +75,10 @@ class AppTest {
|
||||
@Test
|
||||
void testGetSedanCarsOwnedSortedByDate() {
|
||||
var john = new Person(cars);
|
||||
var modelsExpected = List.of(
|
||||
new Car("Dodge", "Avenger", 2010, Category.SEDAN),
|
||||
new Car("Ford", "Focus", 2012, Category.SEDAN)
|
||||
);
|
||||
var modelsExpected =
|
||||
List.of(
|
||||
new Car("Dodge", "Avenger", 2010, Category.SEDAN),
|
||||
new Car("Ford", "Focus", 2012, Category.SEDAN));
|
||||
var modelsFunctional = FunctionalProgramming.getSedanCarsOwnedSortedByDate(List.of(john));
|
||||
var modelsImperative = ImperativeProgramming.getSedanCarsOwnedSortedByDate(List.of(john));
|
||||
assertEquals(modelsExpected, modelsFunctional);
|
||||
|
||||
Reference in new issue
Block a user