Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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);
}
}

}
Original file line number Diff line number Diff line change
@@ -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);
}
}
}
Original file line number Diff line number Diff line change
@@ -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);
}

}
Original file line number Diff line number Diff line change
@@ -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;
}

}
Original file line number Diff line number Diff line change
@@ -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());
}

}
Original file line number Diff line number Diff line change
@@ -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());
}

}
Original file line number Diff line number Diff line change
@@ -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());
}


}
Loading