mirror of
https://github.com/tiennm99/java-design-patterns.git
synced 2026-08-11 02:22:34 +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:
@@ -28,19 +28,17 @@ import java.time.LocalDate;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* Currying decomposes a function with multiple arguments in multiple functions that
|
||||
* take a single argument. A curried function which has only been passed some of its
|
||||
* arguments is called a partial application. Partial application is useful since it can
|
||||
* be used to create specialised functions in a concise way.
|
||||
*
|
||||
* <p>In this example, a librarian uses a curried book builder function create books belonging to
|
||||
* desired genres and written by specific authors.
|
||||
*/
|
||||
* Currying decomposes a function with multiple arguments in multiple functions that take a single
|
||||
* argument. A curried function which has only been passed some of its arguments is called a partial
|
||||
* application. Partial application is useful since it can be used to create specialised functions
|
||||
* in a concise way.
|
||||
*
|
||||
* <p>In this example, a librarian uses a curried book builder function create books belonging to
|
||||
* desired genres and written by specific authors.
|
||||
*/
|
||||
@Slf4j
|
||||
public class App {
|
||||
/**
|
||||
* Main entry point of the program.
|
||||
*/
|
||||
/** Main entry point of the program. */
|
||||
public static void main(String[] args) {
|
||||
LOGGER.info("Librarian begins their work.");
|
||||
|
||||
@@ -55,20 +53,28 @@ public class App {
|
||||
Book.AddTitle rowlingFantasyBooksFunc = fantasyBookFunc.withAuthor("J.K. Rowling");
|
||||
|
||||
// Creates books by Stephen King (horror and fantasy genres)
|
||||
Book shining = kingHorrorBooksFunc.withTitle("The Shining")
|
||||
.withPublicationDate(LocalDate.of(1977, 1, 28));
|
||||
Book darkTower = kingFantasyBooksFunc.withTitle("The Dark Tower: Gunslinger")
|
||||
Book shining =
|
||||
kingHorrorBooksFunc.withTitle("The Shining").withPublicationDate(LocalDate.of(1977, 1, 28));
|
||||
Book darkTower =
|
||||
kingFantasyBooksFunc
|
||||
.withTitle("The Dark Tower: Gunslinger")
|
||||
.withPublicationDate(LocalDate.of(1982, 6, 10));
|
||||
|
||||
// Creates fantasy books by J.K. Rowling
|
||||
Book chamberOfSecrets = rowlingFantasyBooksFunc.withTitle("Harry Potter and the Chamber of Secrets")
|
||||
Book chamberOfSecrets =
|
||||
rowlingFantasyBooksFunc
|
||||
.withTitle("Harry Potter and the Chamber of Secrets")
|
||||
.withPublicationDate(LocalDate.of(1998, 7, 2));
|
||||
|
||||
// Create sci-fi books
|
||||
Book dune = scifiBookFunc.withAuthor("Frank Herbert")
|
||||
Book dune =
|
||||
scifiBookFunc
|
||||
.withAuthor("Frank Herbert")
|
||||
.withTitle("Dune")
|
||||
.withPublicationDate(LocalDate.of(1965, 8, 1));
|
||||
Book foundation = scifiBookFunc.withAuthor("Isaac Asimov")
|
||||
Book foundation =
|
||||
scifiBookFunc
|
||||
.withAuthor("Isaac Asimov")
|
||||
.withTitle("Foundation")
|
||||
.withPublicationDate(LocalDate.of(1942, 5, 1));
|
||||
|
||||
@@ -83,4 +89,4 @@ public class App {
|
||||
LOGGER.info(dune.toString());
|
||||
LOGGER.info(foundation.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,9 +29,7 @@ import java.util.Objects;
|
||||
import java.util.function.Function;
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
/**
|
||||
* Book class.
|
||||
*/
|
||||
/** Book class. */
|
||||
@AllArgsConstructor
|
||||
public class Book {
|
||||
private final Genre genre;
|
||||
@@ -49,9 +47,9 @@ public class Book {
|
||||
}
|
||||
Book book = (Book) o;
|
||||
return Objects.equals(author, book.author)
|
||||
&& Objects.equals(genre, book.genre)
|
||||
&& Objects.equals(title, book.title)
|
||||
&& Objects.equals(publicationDate, book.publicationDate);
|
||||
&& Objects.equals(genre, book.genre)
|
||||
&& Objects.equals(title, book.title)
|
||||
&& Objects.equals(publicationDate, book.publicationDate);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -61,57 +59,55 @@ public class Book {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Book{" + "genre=" + genre + ", author='" + author + '\''
|
||||
+ ", title='" + title + '\'' + ", publicationDate=" + publicationDate + '}';
|
||||
return "Book{"
|
||||
+ "genre="
|
||||
+ genre
|
||||
+ ", author='"
|
||||
+ author
|
||||
+ '\''
|
||||
+ ", title='"
|
||||
+ title
|
||||
+ '\''
|
||||
+ ", publicationDate="
|
||||
+ publicationDate
|
||||
+ '}';
|
||||
}
|
||||
|
||||
/**
|
||||
* Curried book builder/creator function.
|
||||
*/
|
||||
static Function<Genre, Function<String, Function<String, Function<LocalDate, Book>>>> book_creator
|
||||
= bookGenre
|
||||
-> bookAuthor
|
||||
-> bookTitle
|
||||
-> bookPublicationDate
|
||||
-> new Book(bookGenre, bookAuthor, bookTitle, bookPublicationDate);
|
||||
/** Curried book builder/creator function. */
|
||||
static Function<Genre, Function<String, Function<String, Function<LocalDate, Book>>>>
|
||||
book_creator =
|
||||
bookGenre ->
|
||||
bookAuthor ->
|
||||
bookTitle ->
|
||||
bookPublicationDate ->
|
||||
new Book(bookGenre, bookAuthor, bookTitle, bookPublicationDate);
|
||||
|
||||
/**
|
||||
* Implements the builder pattern using functional interfaces to create a more readable book
|
||||
* creator function. This function is equivalent to the BOOK_CREATOR function.
|
||||
*/
|
||||
public static AddGenre builder() {
|
||||
return genre
|
||||
-> author
|
||||
-> title
|
||||
-> publicationDate
|
||||
-> new Book(genre, author, title, publicationDate);
|
||||
return genre ->
|
||||
author -> title -> publicationDate -> new Book(genre, author, title, publicationDate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Functional interface which adds the genre to a book.
|
||||
*/
|
||||
/** Functional interface which adds the genre to a book. */
|
||||
public interface AddGenre {
|
||||
Book.AddAuthor withGenre(Genre genre);
|
||||
}
|
||||
|
||||
/**
|
||||
* Functional interface which adds the author to a book.
|
||||
*/
|
||||
/** Functional interface which adds the author to a book. */
|
||||
public interface AddAuthor {
|
||||
Book.AddTitle withAuthor(String author);
|
||||
}
|
||||
|
||||
/**
|
||||
* Functional interface which adds the title to a book.
|
||||
*/
|
||||
/** Functional interface which adds the title to a book. */
|
||||
public interface AddTitle {
|
||||
Book.AddPublicationDate withTitle(String title);
|
||||
}
|
||||
|
||||
/**
|
||||
* Functional interface which adds the publication date to a book.
|
||||
*/
|
||||
/** Functional interface which adds the publication date to a book. */
|
||||
public interface AddPublicationDate {
|
||||
Book withPublicationDate(LocalDate publicationDate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,9 +24,7 @@
|
||||
*/
|
||||
package com.iluwatar.currying;
|
||||
|
||||
/**
|
||||
* Enum representing different book genres.
|
||||
*/
|
||||
/** Enum representing different book genres. */
|
||||
public enum Genre {
|
||||
FANTASY,
|
||||
HORROR,
|
||||
|
||||
@@ -28,12 +28,10 @@ import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Tests that the App can be run without throwing any exceptions.
|
||||
*/
|
||||
/** Tests that the App can be run without throwing any exceptions. */
|
||||
class AppTest {
|
||||
@Test
|
||||
void executesWithoutExceptions() {
|
||||
assertDoesNotThrow(() -> App.main(new String[]{}));
|
||||
assertDoesNotThrow(() -> App.main(new String[] {}));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,36 +26,31 @@ package com.iluwatar.currying;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import java.time.LocalDate;
|
||||
|
||||
/**
|
||||
* Unit tests for the Book class
|
||||
*/
|
||||
/** Unit tests for the Book class */
|
||||
class BookCurryingTest {
|
||||
private static Book expectedBook;
|
||||
|
||||
@BeforeAll
|
||||
public static void initialiseBook() {
|
||||
expectedBook = new Book(Genre.FANTASY,
|
||||
"Dave",
|
||||
"Into the Night",
|
||||
LocalDate.of(2002, 4, 7));
|
||||
expectedBook = new Book(Genre.FANTASY, "Dave", "Into the Night", LocalDate.of(2002, 4, 7));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the expected book can be created via curried functions
|
||||
*/
|
||||
/** Tests that the expected book can be created via curried functions */
|
||||
@Test
|
||||
void createsExpectedBook() {
|
||||
Book builderCurriedBook = Book.builder()
|
||||
.withGenre(Genre.FANTASY)
|
||||
.withAuthor("Dave")
|
||||
.withTitle("Into the Night")
|
||||
.withPublicationDate(LocalDate.of(2002, 4, 7));
|
||||
Book builderCurriedBook =
|
||||
Book.builder()
|
||||
.withGenre(Genre.FANTASY)
|
||||
.withAuthor("Dave")
|
||||
.withTitle("Into the Night")
|
||||
.withPublicationDate(LocalDate.of(2002, 4, 7));
|
||||
|
||||
Book funcCurriedBook = Book.book_creator
|
||||
Book funcCurriedBook =
|
||||
Book.book_creator
|
||||
.apply(Genre.FANTASY)
|
||||
.apply("Dave")
|
||||
.apply("Into the Night")
|
||||
@@ -65,17 +60,15 @@ class BookCurryingTest {
|
||||
assertEquals(expectedBook, funcCurriedBook);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that an intermediate curried function can be used to create the expected book
|
||||
*/
|
||||
/** Tests that an intermediate curried function can be used to create the expected book */
|
||||
@Test
|
||||
void functionCreatesExpectedBook() {
|
||||
Book.AddTitle daveFantasyBookFunc = Book.builder()
|
||||
.withGenre(Genre.FANTASY)
|
||||
.withAuthor("Dave");
|
||||
Book.AddTitle daveFantasyBookFunc = Book.builder().withGenre(Genre.FANTASY).withAuthor("Dave");
|
||||
|
||||
Book curriedBook = daveFantasyBookFunc.withTitle("Into the Night")
|
||||
.withPublicationDate(LocalDate.of(2002, 4, 7));
|
||||
Book curriedBook =
|
||||
daveFantasyBookFunc
|
||||
.withTitle("Into the Night")
|
||||
.withPublicationDate(LocalDate.of(2002, 4, 7));
|
||||
|
||||
assertEquals(expectedBook, curriedBook);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user