Wzorzec projektowy Budowniczy (Builder) jest jednym z wzorców kreacyjnych, którego głównym celem jest wspomaganie tworzenia złożonych obiektów poprzez proces ich budowy etapami. Pozwala on na oddzielenie procesu tworzenia obiektu od jego reprezentacji, dzięki czemu ten sam proces tworzenia może prowadzić do różnych reprezentacji.
Główne Zalety Wzorca Budowniczego
- Etapowa Konstrukcja: Umożliwia rozłożenie procesu tworzenia skomplikowanego obiektu na mniejsze, bardziej zarządzalne etapy.
- Ponowne wykorzystanie kodu: Poprzez separację procesu konstrukcji od jego implementacji możemy ponownie używać tego samego kodu konstrukcyjnego do tworzenia różnych reprezentacji obiektu.
- Elastyczność: Wszechstronność polegająca na tym, że możemy stworzyć różne konfiguracje konkretnego obiektu, nie zmieniając miejsca jego budowy w kodzie źródłowym.
Przykład
Rozważmy proces budowy komputera, który może być skonfigurowany na etapie wyboru procesora, RAM-u, karty graficznej, itp. Zastosowanie wzorca budowniczego pomoże zaplanować i zorganizować ten proces krok po kroku.
Klasa Produktu
Najpierw utwórzmy klasę Komputer, która zawiera wszystkie elementy, które chcemy budować:
public class Komputer {
private String procesor;
private String ram;
private String kartaGraficzna;// Gettery i settery
public void setProcesor(String procesor) {
this.procesor = procesor;
}public void setRam(String ram) {
this.ram = ram;
}public void setKartaGraficzna(String kartaGraficzna) {
this.kartaGraficzna = kartaGraficzna;
}@Override
public String toString() {
return "Komputer [Procesor=" + procesor + ", RAM=" + ram + ", Karta Graficzna=" + kartaGraficzna + "]";
}
}
Interfejs Budowniczego
Następnie definiujemy interfejs BudowniczyKomputera, który deklaruje metody budowy dla różnych części komputera:
public interface BudowniczyKomputera {
void zbudujProcesor();
void zbudujRam();
void zbudujKarteGraficzna();
Komputer getKomputer();
}
Konkretne Implementacje Budowniczego
Teraz możemy stworzyć klasy, które implementują ten interfejs dla różnych konfiguracji komputera. Na przykład, GamingowyBudowniczyKomputera:
public class GamingowyBudowniczyKomputera implements BudowniczyKomputera {
private Komputer komputer;public GamingowyBudowniczyKomputera() {
this.komputer = new Komputer();
}@Override
public void zbudujProcesor() {
komputer.setProcesor("Intel i9");
}@Override
public void zbudujRam() {
komputer.setRam("32GB");
}@Override
public void zbudujKarteGraficzna() {
komputer.setKartaGraficzna("NVIDIA RTX 3080");
}@Override
public Komputer getKomputer() {
return this.komputer;
}
}
Klasa Kierownika
Potrzebujemy jeszcze Kierownika, który będzie odpowiedzialny za zarządzanie procesem budowy:
public class Kierownik {
private BudowniczyKomputera budowniczy;public void ustawBudowniczego(BudowniczyKomputera budowniczy) {
this.budowniczy = budowniczy;
}public void zbudujKomputer() {
budowniczy.zbudujProcesor();
budowniczy.zbudujRam();
budowniczy.zbudujKarteGraficzna();
}public Komputer getKomputer() {
return budowniczy.getKomputer();
}
}
Przykład Użycia
Ostatecznie, możemy stworzyć komputer przy użyciu wzorca Budowniczy w następujący sposób:
public class Main {
public static void main(String[] args) {
Kierownik kierownik = new Kierownik();
BudowniczyKomputera gamingowyBudowniczy = new GamingowyBudowniczyKomputera();kierownik.ustawBudowniczego(gamingowyBudowniczy);
kierownik.zbudujKomputer();Komputer gamingowyKomputer = kierownik.getKomputer();
System.out.println(gamingowyKomputer);
}
}
Podsumowanie
Wzorzec budowniczego jest potężnym narzędziem do tworzenia złożonych obiektów krok po kroku. Pozwala on na dużą elastyczność i ponowne wykorzystanie kodu, dzięki czemu proces tworzenia obiektów staje się bardziej zarządzalny i modułowy. Dzięki rozdzieleniu procesu budowy od jego reprezentacji możemy tworzyć różne konfiguracje bez konieczności modyfikowania głównego kodu aplikacji.