diff --git a/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/creational/builder/chain/inner/Task.java b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/creational/builder/chain/inner/Task.java new file mode 100644 index 0000000..3f6bc0a --- /dev/null +++ b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/creational/builder/chain/inner/Task.java @@ -0,0 +1,59 @@ +package pl.mperor.lab.java.design.pattern.creational.builder.chain.inner; + +import java.util.concurrent.atomic.AtomicInteger; + +public class Task { + + private static final AtomicInteger ID_GENERATOR = new AtomicInteger(1); + + private int id; + private String description; + private boolean done; + + private Task() { + } + + private Task(Task task) { + this.id = ID_GENERATOR.getAndIncrement(); + // Deep copy is required here! + this.description = task.description; + this.done = task.done; + } + + public int getId() { + return id; + } + + public String getDescription() { + return description; + } + + public boolean isDone() { + return done; + } + + public static Builder builder() { + return new Task().new Builder(); + } + + public class Builder { + + private Builder() { + } + + public Builder description(String description) { + Task.this.description = description; + return this; + } + + public Builder done(boolean done) { + Task.this.done = done; + return this; + } + + public Task build() { + return new Task(Task.this); + } + } + +} diff --git a/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/creational/builder/chain/nested/User.java b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/creational/builder/chain/nested/User.java new file mode 100644 index 0000000..42ff8cb --- /dev/null +++ b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/creational/builder/chain/nested/User.java @@ -0,0 +1,72 @@ +package pl.mperor.lab.java.design.pattern.creational.builder.chain.nested; + +import java.util.concurrent.atomic.AtomicInteger; + +public class User { + + private static final AtomicInteger ID_GENERATOR = new AtomicInteger(1); + + private int id; + private String name; + private String password; + private String email; + + private User() { + } + + private User(User user) { + this.id = ID_GENERATOR.getAndIncrement(); + // Deep copy is required here! + this.name = user.name; + this.password = user.password; + this.email = user.email; + } + + int getId() { + return id; + } + + public String getName() { + return name; + } + + public String getPassword() { + return password; + } + + public String getEmail() { + return email; + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + + private final User user; + + private Builder() { + this.user = new User(); + } + + public Builder name(String name) { + this.user.name = name; + return this; + } + + public Builder password(String password) { + user.password = password; + return this; + } + + public Builder email(String email) { + user.email = email; + return this; + } + + public User build() { + return new User(user); + } + } +} diff --git a/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/creational/builder/chain/outer/Person.java b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/creational/builder/chain/outer/Person.java new file mode 100644 index 0000000..e914d08 --- /dev/null +++ b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/creational/builder/chain/outer/Person.java @@ -0,0 +1,39 @@ +package pl.mperor.lab.java.design.pattern.creational.builder.chain.outer; + +import java.time.LocalDate; + +public class Person { + + private final String firstName; + private final String lastName; + private final LocalDate dateOfBirth; + private final String address; + + private Person(PersonBuilder builder) { + this.firstName = builder.getFirstName(); + this.lastName = builder.getLastName(); + this.dateOfBirth = builder.getDateOfBirth(); + this.address = builder.getAddress(); + } + + public String getFirstName() { + return firstName; + } + + public String getLastName() { + return lastName; + } + + public LocalDate getDateOfBirth() { + return dateOfBirth; + } + + public String getAddress() { + return address; + } + + public static Person build(PersonBuilder builder) { + return new Person(builder); + } + +} diff --git a/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/creational/builder/chain/outer/PersonBuilder.java b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/creational/builder/chain/outer/PersonBuilder.java new file mode 100644 index 0000000..ffed06c --- /dev/null +++ b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/creational/builder/chain/outer/PersonBuilder.java @@ -0,0 +1,48 @@ +package pl.mperor.lab.java.design.pattern.creational.builder.chain.outer; + +import java.time.LocalDate; + +public class PersonBuilder { + + private String firstName; + private String lastName; + private LocalDate dateOfBirth; + private String address; + + public PersonBuilder firstName(String name) { + this.firstName = name; + return this; + } + + public PersonBuilder lastName(String name) { + this.lastName = name; + return this; + } + + public PersonBuilder dateOfBirth(LocalDate date) { + this.dateOfBirth = date; + return this; + } + + public PersonBuilder address(String address) { + this.address = address; + return this; + } + + public String getFirstName() { + return firstName; + } + + public String getLastName() { + return lastName; + } + + public LocalDate getDateOfBirth() { + return dateOfBirth; + } + + public String getAddress() { + return address; + } + +} \ No newline at end of file diff --git a/DesignPatterns/src/test/java/pl/mperor/lab/java/design/pattern/creational/builder/chain/inner/TaskInnerBuilderTest.java b/DesignPatterns/src/test/java/pl/mperor/lab/java/design/pattern/creational/builder/chain/inner/TaskInnerBuilderTest.java new file mode 100644 index 0000000..00862a7 --- /dev/null +++ b/DesignPatterns/src/test/java/pl/mperor/lab/java/design/pattern/creational/builder/chain/inner/TaskInnerBuilderTest.java @@ -0,0 +1,38 @@ +package pl.mperor.lab.java.design.pattern.creational.builder.chain.inner; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class TaskInnerBuilderTest { + + @Test + public void builderShouldAllowToBuildTask() { + Task task = Task.builder() + .build(); + + Assertions.assertNotNull(task); + Assertions.assertTrue(task.getId() >= 1); + Assertions.assertNull(task.getDescription()); + Assertions.assertFalse(task.isDone()); + } + + @Test + public void builderShouldAllowToBuildDoneTasks() { + var builder = Task.builder() + .done(true); + + Task t1 = builder + .description("First task") + .build(); + + Task t2 = builder + .description("Second task") + .build(); + + Assertions.assertEquals("First task", t1.getDescription()); + Assertions.assertEquals("Second task", t2.getDescription()); + Assertions.assertTrue(t1.isDone() && t2.isDone()); + Assertions.assertNotEquals(t1.getId(), t2.getId()); + } + +} \ No newline at end of file diff --git a/DesignPatterns/src/test/java/pl/mperor/lab/java/design/pattern/creational/builder/chain/nested/UserNestedStaticBuilderTest.java b/DesignPatterns/src/test/java/pl/mperor/lab/java/design/pattern/creational/builder/chain/nested/UserNestedStaticBuilderTest.java new file mode 100644 index 0000000..69431e1 --- /dev/null +++ b/DesignPatterns/src/test/java/pl/mperor/lab/java/design/pattern/creational/builder/chain/nested/UserNestedStaticBuilderTest.java @@ -0,0 +1,56 @@ +package pl.mperor.lab.java.design.pattern.creational.builder.chain.nested; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class UserNestedStaticBuilderTest { + + @Test + public void userBuilderShouldAllowToBuildUser() { + User user = User.builder().build(); + Assertions.assertNotNull(user); + Assertions.assertTrue(user.getId() >= 1); + Assertions.assertNull(user.getName()); + Assertions.assertNull(user.getPassword()); + } + + @Test + public void userBuilderShouldAllowToBuildCustomUser() { + User custom = User.builder() + .name("user") + .password("{noop}password") + .email("user@example.com") + .build(); + + Assertions.assertTrue(custom.getId() >= 1); + Assertions.assertEquals("user", custom.getName()); + Assertions.assertNotNull(custom.getPassword()); + Assertions.assertEquals("user@example.com", custom.getEmail()); + } + + @Test + public void userBuilderShouldAllowToBuildGroupOfUsers() { + var builder = User.builder(); + User u1 = builder + .name("Anonymous") + .email("anonymous@example.com") + .build(); + Assertions.assertEquals("Anonymous", u1.getName()); + Assertions.assertEquals("anonymous@example.com", u1.getEmail()); + + User u2 = builder + .email("admin@example.com") + .build(); + Assertions.assertEquals("Anonymous", u2.getName()); + Assertions.assertEquals("admin@example.com", u2.getEmail()); + + User u3 = User.builder() + .email("noname@example.com") + .build(); + Assertions.assertNull(u3.getName()); + Assertions.assertEquals("noname@example.com", u3.getEmail()); + + Assertions.assertTrue(u1.getId() < u2.getId() && u2.getId() < u3.getId()); + } + +} \ No newline at end of file diff --git a/DesignPatterns/src/test/java/pl/mperor/lab/java/design/pattern/creational/builder/chain/outer/PersonOuterBuilderTest.java b/DesignPatterns/src/test/java/pl/mperor/lab/java/design/pattern/creational/builder/chain/outer/PersonOuterBuilderTest.java new file mode 100644 index 0000000..8b86a7e --- /dev/null +++ b/DesignPatterns/src/test/java/pl/mperor/lab/java/design/pattern/creational/builder/chain/outer/PersonOuterBuilderTest.java @@ -0,0 +1,27 @@ +package pl.mperor.lab.java.design.pattern.creational.builder.chain.outer; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.time.LocalDate; +import java.time.Month; + +public class PersonOuterBuilderTest { + + @Test + public void personShouldBeCreatedByPersonBuilder() { + Person person = Person.build(new PersonBuilder() + .firstName("Jack") + .lastName("Bell") + .address("New York") + .dateOfBirth(LocalDate.of(1990, Month.JANUARY, 1))); + + Assertions.assertNotNull(person); + Assertions.assertEquals("Jack", person.getFirstName()); + Assertions.assertEquals("Bell", person.getLastName()); + Assertions.assertEquals("New York", person.getAddress()); + Assertions.assertEquals("1990-01-01", person.getDateOfBirth().toString()); + } + + +} \ No newline at end of file