From 67996222ca6fe57caf2753f067e0aa2330f48e48 Mon Sep 17 00:00:00 2001 From: Janus Date: Fri, 15 Oct 2021 00:12:03 +0800 Subject: [PATCH 01/21] Add currying pattern code --- currying/pom.xml | 43 ++++++++++++ .../java/com/iluwatar/currying/Staff.java | 65 +++++++++++++++++++ pom.xml | 1 + 3 files changed, 109 insertions(+) create mode 100644 currying/pom.xml create mode 100644 currying/src/main/java/com/iluwatar/currying/Staff.java diff --git a/currying/pom.xml b/currying/pom.xml new file mode 100644 index 000000000000..b86c13c28395 --- /dev/null +++ b/currying/pom.xml @@ -0,0 +1,43 @@ + + + + + java-design-patterns + com.iluwatar + 1.18.0-SNAPSHOT + + 4.0.0 + currying + + + junit + junit + test + + + \ No newline at end of file diff --git a/currying/src/main/java/com/iluwatar/currying/Staff.java b/currying/src/main/java/com/iluwatar/currying/Staff.java new file mode 100644 index 000000000000..571c580d7a57 --- /dev/null +++ b/currying/src/main/java/com/iluwatar/currying/Staff.java @@ -0,0 +1,65 @@ +package com.iluwatar.currying; + +import java.time.LocalDate; +import java.util.Objects; +import java.util.function.Function; + +public class Staff { + private String firstName; + private String lastName; + private Gender gender; + private String email; + private LocalDate dateOfBirth; + + public Staff(String firstName, String lastName, Gender gender, String email, LocalDate dateOfBirth) { + this.firstName = firstName; + this.lastName = lastName; + this.gender = gender; + this.email = email; + this.dateOfBirth = dateOfBirth; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Staff staff = (Staff) o; + return firstName.equals(staff.firstName) && lastName.equals(staff.lastName) && gender == staff.gender && email.equals(staff.email) && dateOfBirth.equals(staff.dateOfBirth); + } + + @Override + public int hashCode() { + return Objects.hash(firstName, lastName, gender, email, dateOfBirth); + } + + static Function>>>> CREATOR = + firstName -> lastName -> gender -> email -> dateOfBirth -> new Staff(firstName, lastName, gender, email, dateOfBirth); + + static AddFirstName builder() { + return firstName -> lastName -> gender -> email -> dateOfBirth -> new Staff(firstName, lastName, gender, email, dateOfBirth); + } + + interface AddFirstName { + AddLastName withReturnFirstName(String firstName); + } + + interface AddLastName { + AddGender withReturnLastName(String lastName); + } + + interface AddGender { + AddEmail withReturnGender(Gender gender); + } + + interface AddEmail { + AddDateOfBirth withReturnEmail(String email); + } + + interface AddDateOfBirth { + Staff withReturnDateOfBirth(LocalDate dateOfBirth); + } + + enum Gender { + Male, Female + } +} diff --git a/pom.xml b/pom.xml index f94b9923006a..7eccd94088ed 100644 --- a/pom.xml +++ b/pom.xml @@ -152,6 +152,7 @@ eip-splitter eip-aggregator retry + currying From e3b95853a78e9930fc36082e8161038ed09f66bb Mon Sep 17 00:00:00 2001 From: Janus Date: Fri, 15 Oct 2021 00:13:14 +0800 Subject: [PATCH 02/21] Add currying pattern code --- .../java/com/iluwatar/currying/StaffTest.java | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 currying/src/test/java/com/iluwatar/currying/StaffTest.java diff --git a/currying/src/test/java/com/iluwatar/currying/StaffTest.java b/currying/src/test/java/com/iluwatar/currying/StaffTest.java new file mode 100644 index 000000000000..8a65bbe727fd --- /dev/null +++ b/currying/src/test/java/com/iluwatar/currying/StaffTest.java @@ -0,0 +1,38 @@ +package com.iluwatar.currying; + +import org.junit.Assert; +import org.junit.Test; + +import java.time.LocalDate; + +public class StaffTest { + private final String firstName = "Janus"; + private final String lastName = "Lin"; + private final Staff.Gender gender = Staff.Gender.Male; + private final String email = "example@gmail.com"; + private final LocalDate dateOfBirth = LocalDate.now(); + + private final Staff expectedResult = new Staff(firstName, lastName, gender, email, dateOfBirth); + + @Test + public void createStaffWithBasicCurrying() { + Staff actualResult = Staff.CREATOR + .apply(firstName) + .apply(lastName) + .apply(gender) + .apply(email) + .apply(dateOfBirth); + Assert.assertEquals(expectedResult, actualResult); + } + + @Test + public void createStaffWithFunctionalInterface() { + Staff actualResult = Staff.builder() + .withReturnFirstName(firstName) + .withReturnLastName(lastName) + .withReturnGender(gender) + .withReturnEmail(email) + .withReturnDateOfBirth(dateOfBirth); + Assert.assertEquals(expectedResult, actualResult); + } +} From 79327dc03222af644f564166cfd63837459a05d8 Mon Sep 17 00:00:00 2001 From: Janus Date: Fri, 15 Oct 2021 00:51:34 +0800 Subject: [PATCH 03/21] Add currying pattern code --- currying/src/main/java/com/iluwatar/currying/Staff.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/currying/src/main/java/com/iluwatar/currying/Staff.java b/currying/src/main/java/com/iluwatar/currying/Staff.java index 571c580d7a57..254cd701e9ca 100644 --- a/currying/src/main/java/com/iluwatar/currying/Staff.java +++ b/currying/src/main/java/com/iluwatar/currying/Staff.java @@ -32,9 +32,15 @@ public int hashCode() { return Objects.hash(firstName, lastName, gender, email, dateOfBirth); } + /** + * Use {@link Function} for currying + */ static Function>>>> CREATOR = firstName -> lastName -> gender -> email -> dateOfBirth -> new Staff(firstName, lastName, gender, email, dateOfBirth); + /** + * Use functional interfaces for currying + */ static AddFirstName builder() { return firstName -> lastName -> gender -> email -> dateOfBirth -> new Staff(firstName, lastName, gender, email, dateOfBirth); } From 7e4bc40f64563babcbe255ba5a9dc06dc1e263ce Mon Sep 17 00:00:00 2001 From: Janus Date: Fri, 15 Oct 2021 00:53:57 +0800 Subject: [PATCH 04/21] Add README for currying --- currying/README.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 currying/README.md diff --git a/currying/README.md b/currying/README.md new file mode 100644 index 000000000000..101c98438a68 --- /dev/null +++ b/currying/README.md @@ -0,0 +1,24 @@ +--- +layout: pattern +title: Currying +folder: currying +permalink: /patterns/currying/ +categories: Architectural +tags: +- Java +- Difficulty-Intermediate +--- + +## Intent +Currying pattern is a function that returns another function which only takes 1 parameter at a time. + +![alt text](./etc/dao.png "Data Access Object") + +## Applicability +Use the currying pattern in any of the following situations + +* when you want to break a function with many arguments into many functions with single argument + +## Credits + +* [J2EE Design Patterns](http://www.amazon.com/J2EE-Design-Patterns-William-Crawford/dp/0596004273/ref=sr_1_2) From a9f875b56e20394bbf4111c2585cd57d8ae66925 Mon Sep 17 00:00:00 2001 From: januslinhc Date: Mon, 18 Oct 2021 23:53:45 +0800 Subject: [PATCH 05/21] Remove wrong credit --- currying/README.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/currying/README.md b/currying/README.md index 101c98438a68..636931447af3 100644 --- a/currying/README.md +++ b/currying/README.md @@ -18,7 +18,3 @@ Currying pattern is a function that returns another function which only takes 1 Use the currying pattern in any of the following situations * when you want to break a function with many arguments into many functions with single argument - -## Credits - -* [J2EE Design Patterns](http://www.amazon.com/J2EE-Design-Patterns-William-Crawford/dp/0596004273/ref=sr_1_2) From 1b902bf128e3a9ac1a18e349dde666eb7c0fc757 Mon Sep 17 00:00:00 2001 From: januslinhc Date: Mon, 18 Oct 2021 23:54:47 +0800 Subject: [PATCH 06/21] fix parent module version --- currying/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/currying/pom.xml b/currying/pom.xml index b86c13c28395..33e2bed1a3b5 100644 --- a/currying/pom.xml +++ b/currying/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.18.0-SNAPSHOT + 1.25.0-SNAPSHOT 4.0.0 currying @@ -40,4 +40,4 @@ test - \ No newline at end of file + From 221e0316d34baf6b243c3e7ca1a9b7949862f5cf Mon Sep 17 00:00:00 2001 From: Janus Date: Tue, 19 Oct 2021 01:20:27 +0800 Subject: [PATCH 07/21] fix style --- .../java/com/iluwatar/currying/Staff.java | 137 +++++++++++------- 1 file changed, 86 insertions(+), 51 deletions(-) diff --git a/currying/src/main/java/com/iluwatar/currying/Staff.java b/currying/src/main/java/com/iluwatar/currying/Staff.java index 254cd701e9ca..9f3539e78d99 100644 --- a/currying/src/main/java/com/iluwatar/currying/Staff.java +++ b/currying/src/main/java/com/iluwatar/currying/Staff.java @@ -4,68 +4,103 @@ import java.util.Objects; import java.util.function.Function; +/** + * Staff Object for demonstrating how to use currying pattern. + */ public class Staff { - private String firstName; - private String lastName; - private Gender gender; - private String email; - private LocalDate dateOfBirth; + private String firstName; + private String lastName; + private Gender gender; + private String email; + private LocalDate dateOfBirth; - public Staff(String firstName, String lastName, Gender gender, String email, LocalDate dateOfBirth) { - this.firstName = firstName; - this.lastName = lastName; - this.gender = gender; - this.email = email; - this.dateOfBirth = dateOfBirth; - } + /** + * Contractor. - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Staff staff = (Staff) o; - return firstName.equals(staff.firstName) && lastName.equals(staff.lastName) && gender == staff.gender && email.equals(staff.email) && dateOfBirth.equals(staff.dateOfBirth); - } + * @param firstName first name. + * @param lastName last name. + * @param gender gender. + * @param email email. + * @param dateOfBirth date of birth. + */ + public Staff(String firstName, + String lastName, + Gender gender, + String email, + LocalDate dateOfBirth) { + this.firstName = firstName; + this.lastName = lastName; + this.gender = gender; + this.email = email; + this.dateOfBirth = dateOfBirth; + } - @Override - public int hashCode() { - return Objects.hash(firstName, lastName, gender, email, dateOfBirth); + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; } + Staff staff = (Staff) o; + return firstName.equals(staff.firstName) + && lastName.equals(staff.lastName) + && gender == staff.gender + && email.equals(staff.email) + && dateOfBirth.equals(staff.dateOfBirth); + } - /** - * Use {@link Function} for currying - */ - static Function>>>> CREATOR = - firstName -> lastName -> gender -> email -> dateOfBirth -> new Staff(firstName, lastName, gender, email, dateOfBirth); + @Override + public int hashCode() { + return Objects.hash(firstName, lastName, gender, email, dateOfBirth); + } - /** - * Use functional interfaces for currying - */ - static AddFirstName builder() { - return firstName -> lastName -> gender -> email -> dateOfBirth -> new Staff(firstName, lastName, gender, email, dateOfBirth); - } + /** + * Use {@link Function} for currying. + */ + static Function>>>> CREATOR = + firstName -> lastName + -> gender -> email + -> dateOfBirth + -> new Staff(firstName, lastName, gender, + email, dateOfBirth); - interface AddFirstName { - AddLastName withReturnFirstName(String firstName); - } + /** + * Use functional interfaces for currying. + */ + static AddFirstName builder() { + return firstName -> lastName + -> gender -> email + -> dateOfBirth + -> new Staff(firstName, lastName, gender, email, dateOfBirth); + } - interface AddLastName { - AddGender withReturnLastName(String lastName); - } + interface AddFirstName { + AddLastName withReturnFirstName(String firstName); + } - interface AddGender { - AddEmail withReturnGender(Gender gender); - } + interface AddLastName { + AddGender withReturnLastName(String lastName); + } - interface AddEmail { - AddDateOfBirth withReturnEmail(String email); - } + interface AddGender { + AddEmail withReturnGender(Gender gender); + } - interface AddDateOfBirth { - Staff withReturnDateOfBirth(LocalDate dateOfBirth); - } + interface AddEmail { + AddDateOfBirth withReturnEmail(String email); + } - enum Gender { - Male, Female - } + interface AddDateOfBirth { + Staff withReturnDateOfBirth(LocalDate dateOfBirth); + } + + enum Gender { + Male, Female + } } From b5c50ed57bf755371bd644465df868c9cf1e7619 Mon Sep 17 00:00:00 2001 From: Janus Date: Wed, 20 Oct 2021 00:24:34 +0800 Subject: [PATCH 08/21] add maven-assembly-plugin --- currying/pom.xml | 19 ++++++++++++ .../java/com/iluwatar/currying/Staff.java | 30 +++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/currying/pom.xml b/currying/pom.xml index 33e2bed1a3b5..14ea821bb78b 100644 --- a/currying/pom.xml +++ b/currying/pom.xml @@ -40,4 +40,23 @@ test + + + + org.apache.maven.plugins + maven-assembly-plugin + + + + + + com.iluwatar.dao.App + + + + + + + + diff --git a/currying/src/main/java/com/iluwatar/currying/Staff.java b/currying/src/main/java/com/iluwatar/currying/Staff.java index 9f3539e78d99..38e7f3659432 100644 --- a/currying/src/main/java/com/iluwatar/currying/Staff.java +++ b/currying/src/main/java/com/iluwatar/currying/Staff.java @@ -103,4 +103,34 @@ interface AddDateOfBirth { enum Gender { Male, Female } + + /** + * Main method for maven-assembly-plugin. + */ + public static void main(String[] args) { + final String firstName = "Janus"; + final String lastName = "Lin"; + final Staff.Gender gender = Staff.Gender.Male; + final String email = "example@gmail.com"; + final LocalDate dateOfBirth = LocalDate.now(); + + Staff staff1 = Staff.CREATOR + .apply(firstName) + .apply(lastName) + .apply(gender) + .apply(email) + .apply(dateOfBirth); + + System.out.println(String.format("Staff created with basic currying: %s", staff1)); + + Staff staff2 = Staff.builder() + .withReturnFirstName(firstName) + .withReturnLastName(lastName) + .withReturnGender(gender) + .withReturnEmail(email) + .withReturnDateOfBirth(dateOfBirth); + + System.out.println( + String.format("Staff created with currying and functional interfaces: %s", staff2)); + } } From 7e4c34c002657dcedfa9f3f17755e98e4ed4f380 Mon Sep 17 00:00:00 2001 From: Janus Date: Wed, 20 Oct 2021 00:28:40 +0800 Subject: [PATCH 09/21] Use Lombok to get rid of boilerplate --- .../java/com/iluwatar/currying/Staff.java | 47 ++----------------- 1 file changed, 5 insertions(+), 42 deletions(-) diff --git a/currying/src/main/java/com/iluwatar/currying/Staff.java b/currying/src/main/java/com/iluwatar/currying/Staff.java index 38e7f3659432..e58f88249d7a 100644 --- a/currying/src/main/java/com/iluwatar/currying/Staff.java +++ b/currying/src/main/java/com/iluwatar/currying/Staff.java @@ -1,5 +1,8 @@ package com.iluwatar.currying; +import lombok.AllArgsConstructor; +import lombok.Data; + import java.time.LocalDate; import java.util.Objects; import java.util.function.Function; @@ -7,6 +10,8 @@ /** * Staff Object for demonstrating how to use currying pattern. */ +@AllArgsConstructor +@Data public class Staff { private String firstName; private String lastName; @@ -14,48 +19,6 @@ public class Staff { private String email; private LocalDate dateOfBirth; - /** - * Contractor. - - * @param firstName first name. - * @param lastName last name. - * @param gender gender. - * @param email email. - * @param dateOfBirth date of birth. - */ - public Staff(String firstName, - String lastName, - Gender gender, - String email, - LocalDate dateOfBirth) { - this.firstName = firstName; - this.lastName = lastName; - this.gender = gender; - this.email = email; - this.dateOfBirth = dateOfBirth; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Staff staff = (Staff) o; - return firstName.equals(staff.firstName) - && lastName.equals(staff.lastName) - && gender == staff.gender - && email.equals(staff.email) - && dateOfBirth.equals(staff.dateOfBirth); - } - - @Override - public int hashCode() { - return Objects.hash(firstName, lastName, gender, email, dateOfBirth); - } - /** * Use {@link Function} for currying. */ From 8cd16fef8351cfb882a615a0c2ebc4c639918304 Mon Sep 17 00:00:00 2001 From: Janus Date: Wed, 20 Oct 2021 00:30:15 +0800 Subject: [PATCH 10/21] Update tags in README.md --- currying/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/currying/README.md b/currying/README.md index 636931447af3..43a2defac25a 100644 --- a/currying/README.md +++ b/currying/README.md @@ -5,8 +5,7 @@ folder: currying permalink: /patterns/currying/ categories: Architectural tags: -- Java -- Difficulty-Intermediate +- Decoupling --- ## Intent From 077bd4517ae7949bd0dfccc661472ef08357d9d6 Mon Sep 17 00:00:00 2001 From: Janus Date: Wed, 20 Oct 2021 00:30:59 +0800 Subject: [PATCH 11/21] Update categories in README.md --- currying/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/currying/README.md b/currying/README.md index 43a2defac25a..b70b9b6cf141 100644 --- a/currying/README.md +++ b/currying/README.md @@ -3,7 +3,7 @@ layout: pattern title: Currying folder: currying permalink: /patterns/currying/ -categories: Architectural +categories: Functional tags: - Decoupling --- From bcedc3f3135a34d02d4f36c3d200b30819b4b8cc Mon Sep 17 00:00:00 2001 From: Janus Date: Wed, 20 Oct 2021 00:31:32 +0800 Subject: [PATCH 12/21] add language in README.md --- currying/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/currying/README.md b/currying/README.md index b70b9b6cf141..72c0f57c39df 100644 --- a/currying/README.md +++ b/currying/README.md @@ -4,6 +4,7 @@ title: Currying folder: currying permalink: /patterns/currying/ categories: Functional +language: en tags: - Decoupling --- From 6332fdd7df8315e9cbb5c62e59e250135962b84c Mon Sep 17 00:00:00 2001 From: Janus Date: Wed, 20 Oct 2021 00:52:29 +0800 Subject: [PATCH 13/21] update Tutorials and Credits sections in README.md --- currying/README.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/currying/README.md b/currying/README.md index 72c0f57c39df..c7b8c1663503 100644 --- a/currying/README.md +++ b/currying/README.md @@ -10,7 +10,7 @@ tags: --- ## Intent -Currying pattern is a function that returns another function which only takes 1 parameter at a time. +Currying pattern transforms an arbitrary arity into a sequence of unary functions. ![alt text](./etc/dao.png "Data Access Object") @@ -18,3 +18,11 @@ Currying pattern is a function that returns another function which only takes 1 Use the currying pattern in any of the following situations * when you want to break a function with many arguments into many functions with single argument + +## Tutorials + +* [Currying in Java](https://www.baeldung.com/java-currying) + +## Credits + +* [Baeldung](https://www.baeldung.com/) \ No newline at end of file From ab93ab56c7ad9846e3f204192a2a0ea4ad3727db Mon Sep 17 00:00:00 2001 From: Janus Date: Wed, 20 Oct 2021 01:10:37 +0800 Subject: [PATCH 14/21] add test case for main --- currying/src/test/java/com/iluwatar/currying/StaffTest.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/currying/src/test/java/com/iluwatar/currying/StaffTest.java b/currying/src/test/java/com/iluwatar/currying/StaffTest.java index 8a65bbe727fd..dc4e6be9edbf 100644 --- a/currying/src/test/java/com/iluwatar/currying/StaffTest.java +++ b/currying/src/test/java/com/iluwatar/currying/StaffTest.java @@ -35,4 +35,9 @@ public void createStaffWithFunctionalInterface() { .withReturnDateOfBirth(dateOfBirth); Assert.assertEquals(expectedResult, actualResult); } + + @Test + public void mainTest() { + Staff.main(new String[]{}); + } } From 20466c4aeeffd83401f8da05977f482c21629a08 Mon Sep 17 00:00:00 2001 From: Janus Date: Mon, 25 Oct 2021 00:24:42 +0800 Subject: [PATCH 15/21] fix merge conflict --- dao/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dao/pom.xml b/dao/pom.xml index d9467aeae899..ffe5444e66d8 100644 --- a/dao/pom.xml +++ b/dao/pom.xml @@ -56,7 +56,7 @@ - com.iluwatar.dao.App + com.iluwatar.currying.Staff From 4a93b257db1e28edec7fc1ed8208b4a489c81320 Mon Sep 17 00:00:00 2001 From: Janus Date: Mon, 25 Oct 2021 00:31:54 +0800 Subject: [PATCH 16/21] revert dao change --- dao/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dao/pom.xml b/dao/pom.xml index ffe5444e66d8..d9467aeae899 100644 --- a/dao/pom.xml +++ b/dao/pom.xml @@ -56,7 +56,7 @@ - com.iluwatar.currying.Staff + com.iluwatar.dao.App From 9928e7071bc2c9e63111e94f200e0e2feff8967d Mon Sep 17 00:00:00 2001 From: Janus Date: Mon, 25 Oct 2021 00:33:44 +0800 Subject: [PATCH 17/21] remove diagram --- currying/README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/currying/README.md b/currying/README.md index c7b8c1663503..e5ab7fdf006a 100644 --- a/currying/README.md +++ b/currying/README.md @@ -12,8 +12,6 @@ tags: ## Intent Currying pattern transforms an arbitrary arity into a sequence of unary functions. -![alt text](./etc/dao.png "Data Access Object") - ## Applicability Use the currying pattern in any of the following situations From 34e80af0fde10452de87987508fa27a25aab971b Mon Sep 17 00:00:00 2001 From: Janus Date: Mon, 25 Oct 2021 00:46:43 +0800 Subject: [PATCH 18/21] add test cases --- .../java/com/iluwatar/currying/StaffTest.java | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/currying/src/test/java/com/iluwatar/currying/StaffTest.java b/currying/src/test/java/com/iluwatar/currying/StaffTest.java index dc4e6be9edbf..f74dfb532bd8 100644 --- a/currying/src/test/java/com/iluwatar/currying/StaffTest.java +++ b/currying/src/test/java/com/iluwatar/currying/StaffTest.java @@ -5,6 +5,8 @@ import java.time.LocalDate; +import static org.junit.Assert.*; + public class StaffTest { private final String firstName = "Janus"; private final String lastName = "Lin"; @@ -22,7 +24,7 @@ public void createStaffWithBasicCurrying() { .apply(gender) .apply(email) .apply(dateOfBirth); - Assert.assertEquals(expectedResult, actualResult); + assertEquals(expectedResult, actualResult); } @Test @@ -33,11 +35,24 @@ public void createStaffWithFunctionalInterface() { .withReturnGender(gender) .withReturnEmail(email) .withReturnDateOfBirth(dateOfBirth); - Assert.assertEquals(expectedResult, actualResult); + assertEquals(expectedResult, actualResult); } @Test public void mainTest() { Staff.main(new String[]{}); } + + @Test + public void hashTest() { + expectedResult.hashCode(); + } + + @Test + public void equalTest() { + assertTrue(expectedResult.equals(expectedResult)); + assertFalse(expectedResult.equals(new Integer(1))); + Staff o2 = new Staff(firstName, lastName, gender, email, dateOfBirth); + assertTrue(expectedResult.equals(o2)); + } } From b617468d91ee971b27e18cc5a13b89196b789796 Mon Sep 17 00:00:00 2001 From: Janus Date: Mon, 25 Oct 2021 01:21:41 +0800 Subject: [PATCH 19/21] remove unused import --- currying/src/main/java/com/iluwatar/currying/Staff.java | 1 - 1 file changed, 1 deletion(-) diff --git a/currying/src/main/java/com/iluwatar/currying/Staff.java b/currying/src/main/java/com/iluwatar/currying/Staff.java index e58f88249d7a..7ad0ddb0ad2e 100644 --- a/currying/src/main/java/com/iluwatar/currying/Staff.java +++ b/currying/src/main/java/com/iluwatar/currying/Staff.java @@ -4,7 +4,6 @@ import lombok.Data; import java.time.LocalDate; -import java.util.Objects; import java.util.function.Function; /** From fa9d7cc5bf3a03fa58c58cbaa8f94db6a07a9634 Mon Sep 17 00:00:00 2001 From: Janus Date: Mon, 25 Oct 2021 01:33:49 +0800 Subject: [PATCH 20/21] improve README.md --- currying/README.md | 116 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 109 insertions(+), 7 deletions(-) diff --git a/currying/README.md b/currying/README.md index e5ab7fdf006a..c526220eabb1 100644 --- a/currying/README.md +++ b/currying/README.md @@ -1,21 +1,123 @@ --- -layout: pattern -title: Currying -folder: currying -permalink: /patterns/currying/ -categories: Functional -language: en +layout: pattern title: Currying folder: currying permalink: /patterns/currying/ categories: Functional language: en tags: + - Decoupling + --- ## Intent + Currying pattern transforms an arbitrary arity into a sequence of unary functions. +## Explanation + +Real-world example + +> We have a Staff class for storing employees' information, e.g. firstName, lastName, +> gender, email, etc. We want to adapt currying pattern to simplify the parameters handling, +> we don't need to provide all parameters at the same time. We can provide them one by one +> when we have that data. + +In plain words + +> It helps you to avoid passing the same variable again and again. +> It helps to create a higher order function. It extremely helpful in event handling. +> Little snippets of code can be written and reused with ease. + +Wikipedia says + +> Currying provides a way for working with functions that take multiple arguments, +> and using them in frameworks where functions might take only one argument. +> For example, some analytical techniques can only be applied to functions with a +> single argument. Practical functions frequently take more arguments than this. +> Frege showed that it was sufficient to provide solutions for the single argument +> case, as it was possible to transform a function with multiple arguments into a +> chain of single-argument functions instead. This transformation is the process +> now known as currying. + +**Programmatic Example** + +First, we have the `Staff` class: + +```java + +@AllArgsConstructor +@Data +public class Staff { + private String firstName; + private String lastName; + private Gender gender; + private String email; + private LocalDate dateOfBirth; +} +``` + +By using @AllArgsConstructor from Lombok library, it will generate a constructor with all attributes. All paramaters +need to provide at the same time. + +Next, we will try to use Curry pattern to transforms an arbitrary arity into a sequence of unary functions. + +```java +static Function>>>>CREATOR= + firstName->lastName + ->gender->email + ->dateOfBirth + ->new Staff(firstName,lastName,gender, + email,dateOfBirth); +``` + +With using this way, we can create Staff object by providing parameters one by one: + +```java +Staff.CREATOR + .apply(firstName) + .apply(lastName) + .apply(gender) + .apply(email) + .apply(dateOfBirth); +``` + +We can also use Functional Interface to implement currying function. + +```java +static AddFirstName builder(){ + return firstName->lastName + ->gender->email + ->dateOfBirth + ->new Staff(firstName,lastName,gender,email,dateOfBirth); + } + +interface AddFirstName { + AddLastName withReturnFirstName(String firstName); +} + +interface AddLastName { + AddGender withReturnLastName(String lastName); +} + +interface AddGender { + AddEmail withReturnGender(Gender gender); +} + +interface AddEmail { + AddDateOfBirth withReturnEmail(String email); +} + +interface AddDateOfBirth { + Staff withReturnDateOfBirth(LocalDate dateOfBirth); +} +``` + ## Applicability + Use the currying pattern in any of the following situations -* when you want to break a function with many arguments into many functions with single argument +* when you want to break a function with many arguments into many functions with single argument ## Tutorials From 26f4cae685aa0eced910281b546fab96f873a8f1 Mon Sep 17 00:00:00 2001 From: Janus Date: Mon, 25 Oct 2021 01:34:43 +0800 Subject: [PATCH 21/21] fix style --- currying/src/main/java/com/iluwatar/currying/Staff.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/currying/src/main/java/com/iluwatar/currying/Staff.java b/currying/src/main/java/com/iluwatar/currying/Staff.java index 7ad0ddb0ad2e..762e0159d550 100644 --- a/currying/src/main/java/com/iluwatar/currying/Staff.java +++ b/currying/src/main/java/com/iluwatar/currying/Staff.java @@ -1,10 +1,9 @@ package com.iluwatar.currying; -import lombok.AllArgsConstructor; -import lombok.Data; - import java.time.LocalDate; import java.util.function.Function; +import lombok.AllArgsConstructor; +import lombok.Data; /** * Staff Object for demonstrating how to use currying pattern.