BAEL-6227: fluent interfaces code

This commit is contained in:
emanuel.trandafir 2023-03-12 18:11:07 +01:00
parent 911df283d4
commit e958c942d4
10 changed files with 394 additions and 0 deletions

View File

@ -0,0 +1,46 @@
package com.baeldung.fluentinterface;
import static java.util.Arrays.stream;
import static java.util.stream.Collectors.joining;
public class HtmlDocument {
private final String content;
private HtmlDocument(String html) {
this.content = html;
}
public HtmlDocument() {
this("");
}
public String html() {
return String.format("<html>%s</html>", content);
}
public HtmlDocument header(String header) {
return new HtmlDocument(String.format("%s <h1>%s</h1>", content, header));
}
public HtmlDocument secondaryHeader(String header) {
return new HtmlDocument(String.format("%s <h2>%s</h2>", content, header));
}
public HtmlDocument paragraph(String paragraph) {
return new HtmlDocument(String.format("%s <p>%s</p>", content, paragraph));
}
public HtmlDocument horizontalLine() {
return new HtmlDocument(String.format("%s <hr>", content));
}
public HtmlDocument orderedList(String... items) {
String listItems = stream(items).map(el -> String.format("<li>%s</li>", el)).collect(joining());
return new HtmlDocument(String.format("%s <ol>%s</ol>", content, listItems));
}
public HtmlDocument unorderedList(String... items) {
String listItems = stream(items).map(el -> String.format("<li>%s</li>", el)).collect(joining());
return new HtmlDocument(String.format("%s <ul>%s</ul>", content, listItems));
}
}

View File

@ -0,0 +1,40 @@
package com.baeldung.fluentinterface;
import com.baeldung.fluentinterface.components.HtmlElement;
import com.baeldung.fluentinterface.components.HtmlHeader;
import com.baeldung.fluentinterface.components.HtmlList;
import static java.lang.String.format;
import static java.util.Arrays.stream;
import static java.util.stream.Collectors.joining;
public class LargeHtmlDocument {
private final String content;
private LargeHtmlDocument(String html) {
this.content = html;
}
public LargeHtmlDocument() {
this("");
}
public String html() {
return format("<html>%s</html>", content);
}
public LargeHtmlDocument head(HtmlElement head) {
return new LargeHtmlDocument(format("%s <head>%s</head>", content, head.html()));
}
public LargeHtmlDocument body(HtmlElement body) {
return new LargeHtmlDocument(format("%s <body>%s</body>", content, body.html()));
}
public LargeHtmlDocument footer(HtmlElement footer) {
return new LargeHtmlDocument(format("%s <footer>%s</footer>", content, footer.html()));
}
private LargeHtmlDocument append(String html) {
return new LargeHtmlDocument(format("%s %s", content, html));
}
}

View File

@ -0,0 +1,65 @@
package com.baeldung.fluentinterface;
public class User {
private String firstName;
private String lastName;
private String email;
private String username;
private Long id;
public String name() {
return firstName + " " + lastName;
}
public User(String firstName, String lastName, String email, String username, Long id) {
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
this.username = username;
this.id = id;
}
public static Builder builder() {
return new Builder();
}
public static class Builder {
private String firstName;
private String lastName;
private String email;
private String username;
private Long id;
private Builder() {
}
public Builder firstName(String firstName) {
this.firstName = firstName;
return this;
}
public Builder lastName(String lastName) {
this.lastName = lastName;
return this;
}
public Builder email(String email) {
this.email = email;
return this;
}
public Builder username(String username) {
this.username = username;
return this;
}
public Builder id(Long id) {
this.id = id;
return this;
}
public User build() {
return new User(firstName, lastName, email, username, id);
}
}
}

View File

@ -0,0 +1,8 @@
package com.baeldung.fluentinterface.components;
public class HorizontalLine implements HtmlElement {
@Override
public String html() {
return "<hr>";
}
}

View File

@ -0,0 +1,29 @@
package com.baeldung.fluentinterface.components;
public class HtmlDiv implements HtmlElement {
private final String content;
public HtmlDiv(String content) {
this.content = content;
}
public HtmlDiv() {
this.content = "";
}
public HtmlDiv append(HtmlElement element) {
return new HtmlDiv(content + element.html());
}
public HtmlDiv text(String text) {
return new HtmlDiv(content + text);
}
public HtmlDiv paragraph(String text) {
return new HtmlDiv(content + text);
}
@Override
public String html() {
return String.format("<div>%s</div>", content);
}
}

View File

@ -0,0 +1,5 @@
package com.baeldung.fluentinterface.components;
public interface HtmlElement {
String html();
}

View File

@ -0,0 +1,34 @@
package com.baeldung.fluentinterface.components;
public class HtmlHeader implements HtmlElement {
private final Type type;
private final String value;
public HtmlHeader(Type type, String value) {
this.type = type;
this.value = value;
}
@Override
public String html() {
return String.format("<%s>%s</%s>", type.tag(), value, type.tag());
}
public enum Type {
PRIMARY("h1"),
SECONDARY("h2"),
THIRD("h3"),
FOURTH("h4");
private final String tag;
Type(String tag) {
this.tag = tag;
}
public String tag() {
return tag;
}
}
}

View File

@ -0,0 +1,39 @@
package com.baeldung.fluentinterface.components;
import java.util.Arrays;
import java.util.List;
import static java.lang.String.format;
import static java.util.stream.Collectors.joining;
public class HtmlList implements HtmlElement {
private final Type type;
private final List<String> items;
public HtmlList(Type type, String... items) {
this.type = type;
this.items = Arrays.asList(items);
}
@Override
public String html() {
String listItems = items.stream().map(el -> format("<li>%s</li>", el)).collect(joining());
return String.format("<%s>%s</%s>", type.tag(), listItems, type.tag());
}
public enum Type {
ORDERED("ol"),
UNORDERED("ul");
private final String tag;
Type(String tag) {
this.tag = tag;
}
public String tag() {
return tag;
}
}
}

View File

@ -0,0 +1,27 @@
package com.baeldung.fluentinterface.components;
public class HtmlSpan implements HtmlElement {
private final String content;
public HtmlSpan(String content) {
this.content = content;
}
public HtmlSpan() {
this.content = "";
}
public HtmlSpan append(HtmlElement element) {
return new HtmlSpan(content + element.html());
}
public HtmlSpan paragraph(String text) {
return new HtmlSpan(content + text);
}
@Override
public String html() {
return String.format("<span>%s</span>", content);
}
}

View File

@ -0,0 +1,101 @@
package com.baeldung.fluentinterface;
import com.baeldung.fluentinterface.components.*;
import com.baeldung.fluentinterface.components.HtmlHeader.Type;
import org.junit.jupiter.api.Test;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static com.baeldung.fluentinterface.components.HtmlList.Type.ORDERED;
import static org.assertj.core.api.Assertions.assertThat;
class FluentInterfaceUnitTest {
@Test
void givenTenNumbers_thenStreamIsProcessedCorrectly() {
Stream<Integer> numbers = Stream.of(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
Stream<String> processedNumbers = numbers.distinct()
.filter(nr -> nr % 2 == 0)
.skip(1)
.limit(4)
.map(nr -> "#" + nr)
.peek(nr -> System.out.println(nr));
String result = processedNumbers.collect(Collectors.joining(", "));
assertThat(result).isEqualTo("#2, #4, #6, #8");
}
@Test
void givenUserBuilder_thenCreateUserCorrectly() {
User.Builder userBuilder = User.builder();
userBuilder = userBuilder
.firstName("John")
.lastName("Doe")
.email("jd@gmail.com")
.username("jd_2000")
.id(1234L);
User user = userBuilder.build();
assertThat(user.name()).isEqualTo("John Doe");
}
@Test
void givenHtmlDocument_thenGenerateHtmlCorrectly() {
HtmlDocument document = new HtmlDocument()
.header("Principles of O.O.P.")
.paragraph("OOP in Java.")
.horizontalLine()
.paragraph("The main pillars of OOP are:")
.orderedList("Encapsulation", "Inheritance", "Abstraction", "Polymorphism");
String html = document.html();
assertThat(html).isEqualToIgnoringWhitespace(
"<html>"
+ "<h1>Principles of O.O.P.</h1>"
+ "<p>OOP in Java.</p>"
+ "<hr>"
+ "<p>The main pillars of OOP are:</p>"
+ "<ol>"
+ "<li>Encapsulation</li>"
+ "<li>Inheritance</li>"
+ "<li>Abstraction</li>"
+ "<li>Polymorphism</li>"
+ "</ol>"
+ "</html>"
);
}
@Test
void givenHtmlDocument_thenInstanceIsImmutable() {
HtmlDocument document = new HtmlDocument()
.header("Principles of O.O.P.");
HtmlDocument updatedDocument = document
.paragraph("OOP in Java.");
assertThat(document).isNotEqualTo(updatedDocument);
}
@Test
void givenLargeHtmlDocument_thenGenerateHtmlCorrectly() {
String html = new LargeHtmlDocument()
.head(new HtmlHeader(Type.PRIMARY, "title"))
.body(new HtmlDiv()
.append(new HtmlSpan()
.paragraph("learning OOP from John Doe")
.append(new HorizontalLine())
.paragraph("The pillars of OOP:")
)
.append(new HtmlList(ORDERED, "Encapsulation", "Inheritance", "Abstraction", "Polymorphism"))
)
.footer(new HtmlDiv()
.paragraph("trademark John Doe")
)
.html();
String expectedHtml = "<html> <head><h1>title</h1></head> <body><div><span>learning OOP from John Doe<hr>The pillars of OOP:</span><ol><li>Encapsulation</li><li>Inheritance</li><li>Abstraction</li><li>Polymorphism</li></ol></div></body> <footer><div>trademark John Doe</div></footer></html>";
assertThat(html).isEqualToIgnoringWhitespace(expectedHtml);
}
}