Kurs Java

Builder

Wzorzec Builder to prawdopodobnie najczęściej stosowany wzorzec projektowy w Javie. Umożliwia on wieloetapowe budowanie obiektu, które wykonywane jest przez specjalnie przygotowany do tego zadania obiekt budujący (budowniczy, z ang. builder).

Budowanie

Przejdźmy od razu do omówienia konkretnego przykładu. Zbudujemy obiekt klasy DocumentItem. Naszym builderem będzie klasa DocumentItemBuilder. Klasa ta ma za zadanie tylko i wyłącznie zajmować się budową dokumentu, więc możemy ją umieścić w ciele klasy DocumentItem. Klasa jest statyczna, ponieważ chcemy mieć do niej dostęp w kontekście statycznym (buildera będziemy inicjalizować za pomocą metody statycznej builder).
Java CheckedException
Warto podkreślić, że podczas budowania obiektu decydujemy jakie pola mają zostać zainicjowane. Trzy przykłady tworzenia obieku, każdy z innym "wypełnieniem":

DocumentItem documentItem = DocumentItem
        .builder()
        .title("Contract between X and Y")
        .build();

DocumentItem documentItem = DocumentItem
        .builder()
        .title("Contract between X and Y")
        .category(DocumentCategory.of("Contract"))
        .build();

DocumentItem documentItem = DocumentItem
        .builder()
        .title("Contract between X and Y")
        .category(DocumentCategory.of("Contract"))
        .signatures(Arrays.asList("Kowalski", "Nowak"))
        .build();

Uruchomienie każdej kolejnej metody stanowi etap budowania (stąd pojęcie "wieloetapowość"). W uzasadnionych przypadkach możemy rozbić budowę obiektu na części:

DocumentItem.DocumentItemBuilder documentItemBuilder = DocumentItem
                                                            .builder()
                                                            .title("Contract between X and Y");

// inny kod

documentItemBuilder.category(DocumentCategory.of("Contract")).build();
Kod klasy buildera do skopiowania:
import java.util.List;
import java.util.stream.Collectors;

class DocumentItem {

    private final String title;
    private final DocumentCategory category;
    private final List<String> signatures;

    private DocumentItem(String title, DocumentCategory category, List<String> signatures) {
        this.title = title;
        this.category = category;
        this.signatures = signatures;
    }

    static DocumentItemBuilder builder() {
        return new DocumentItemBuilder();
    }

    public String toString() {
        return "DocumentItem(title=" + this.title + ", \ncategory=" + this.category
                + ", \nsignatures=" + this.signatures.stream()
                                           .map(String::toString)
                                           .collect(Collectors.joining(",")) + ")";
    }

    static class DocumentItemBuilder {

        private String title;
        private DocumentCategory category;
        private List<String> signatures;

        DocumentItemBuilder title(String title) {
            this.title = title;
            return this;
        }

        DocumentItemBuilder category(DocumentCategory category) {
            this.category = category;
            return this;
        }

        DocumentItemBuilder signatures(List<String> signatures) {
            this.signatures = signatures;
            return this;
        }

        DocumentItem build() {
            return new DocumentItem(title, category, signatures);
        }
    }
}

Uruchomienie

Zanim wykorzystamy naszego buildera, rzućmy jeszcze okiem na klasę kategorii dokumentu. Do zbudowania tej klasy moglibyśmy również użyć buildera, ale klasa ta jest na tyle prosta, że użyjemy jedynie z metody budującej of (przy okazji to też przykład fajnego sposobu na tworzenie obiektu klasy w dedykowanej metodzie):
class DocumentCategory {

    private final String name;

    private DocumentCategory(String name) {
        this.name = name;
    }

    static DocumentCategory of(String name) {
        return new DocumentCategory(name);
    }

    public String toString() {
        return "DocumentCategory(name=" + this.name + ")";
    }
}
Uruchamiamy nasz kod budujący klasę DocumentItem i drukujemy jego zawartość na konsolę (System.out.println wywołuje tutaj niejawnie metodę toString na obiekcie documentItem):
import java.util.Arrays;

public class Start {

    public static void main(String[] args) {

        DocumentItem documentItem = DocumentItem
                .builder()
                .title("Contract between X and Y")
                .category(DocumentCategory.of("Contract"))
                .signatures(Arrays.asList("Kowalski", "Nowak"))
                .build();

        System.out.println(documentItem);
    }
}
Wynik wykonania kodu:
Wzorce projektowe Java - Builder
Appa Notka. A teraz ciekawostka. Niemal identycznie wygląda klasa budująca, którą stworzy nam Lombok, gdy użyjemy adnotacji @Builder, a następnie wykonamy Delombok w IntelliJ:
Java CheckedException
Jeśli interesują Cię wzorce projektowe, możesz być również zainteresowany naszym Kursem Aplikacji Web, w którym uczysz się kompleksowo Springa, Hibernate'a i innych aktualnych rozwiązań technologicznych na bazie gotowej aplikacji webowej. Oto co dokładnie znajdziesz w kursie:
  • Kurs implementacji aplikacji webowej zbudowanej za pomocą:
    • Spring Boot 2, Spring Framework 5, Spring Data JPA, Spring MVC
    • Spring Security, Spring AOP
    • Hibernate
    • REST Api, Format JSON
    • Maven
    Aplikacja obejmuje funkcjonalności od rejestracji użytkownika i logowania, przez tworzenie, edycję oraz usuwanie danych, aż po różne formy prezentacji, w tym tabele i wykresy. Kurs obejmuje również implementację resetowania hasła z linkiem potwierdzającym wysyłanym na adres email.
  • Atak CSRF i jak się przed nim bronić w Springu
  • Clickjacking za pomocą iframe - jak się zabezpieczyć za pomocą Spring Security
  • CORS i jego możliwe opcje w Springu
  • Testowanie CORS-a z użyciem cURL
  • Dodatkowy projekt do nauki samego Hibernate'a, przygotowany w dwóch wersjach (z Lombokiem i bez). Ta część bazy wiedzy zawiera ponad 60 omówionych snippetów kodu, wzbogaconych dodatkowo ponad 40 zdjęciami. W projekcie zostały zaimplementowane i omówione między innymi:
    • Podstawy Hibernate'a (adnotacje, encje itp.)
    • Wszystkie rodzaje relacji bazodanowych
    • Orphan Removal
    • Single Table Discriminator
    • Table Per Class
  • ...oraz wiele innych zagadnień.
Sam kurs implementacji aplikacji to ponad 150 stron (całość online) analizy kodu od frontendu przez REST-owe wysyłanie żądań i odbieranie odpowiedzi, po zapis w bazie i wizualizowanie zapisu we frontendzie. Dokładnie rozpisane ścieżki w kodzie z tabelami kolejnych kroków dla poszczególnych funkcjonalności. Drogowskazy do ogromnej bazy wiedzy dołączonej w postaci kursów Spring i Hibernate (z projektami wspierającymi naukę).
Zobacz aplikację
Zdjęcie autora
Autor: Jarek Klimas
Data: 03 stycznia 2024
Labele: Backend, Podstawowy, Java

Stale się rozwijamy, a więc bądź na bieżąco!
Na ten adres będziemy przesyłać informacje o ważniejszych aktualizacjach, a także o nowych materiałach pojawiających się na stronie.
Polub nas na Facebooku:
Nasi partnerzy: stackshare
Javappa to również profesjonalne usługi programistyczne oparte o technologie JAVA. Jeśli chesz nawiązać z nami kontakt w celu uzyskania doradztwa bądź stworzenia aplikacji webowej powinieneś poznać nasze doświadczenia.
Kliknij O nas .


Pozycjonowanie stron: Grupa TENSE