I. Wzorce kreacyjne
1. Singleton
2. Budowniczy
3. Prototyp
4. Fabryka
5. Fabryka abstrakcyjna
II. Wzorce strukturalne
1. Adapter
2. Most
3. Kompozyt
4. Dekorator
5. Fasada
6. Pyłek
7. Pełnomocnik
III. Wzorce czynnościowe
1. Łańcuch zobowiązań
2. Polecenie
3. Interpreter
4. Iterator
5. Mediator
6. Pamiątka
7. Obserwator
8. Stan
9. Strategia
10. Metoda szablonowa
11. Odwiedzający

Budowniczy (builder) - wzorzec projektowy (design pattern) - java

1. Cel:
Wzorzec projektowy Budowniczy (builder) ma za zadanie ukryć złożoność tworzenia obiektów.
Hermetyzuje i składa część złożonego obiektu w oddzielnym obiekcie konstruktora.

2. Problem:
Budowniczy jest używany aby oddzielić budowę złożonego obiektu od jego reprezentacji.
Proces budowy powoduje możliwość tworzenia różnych reprezentacji.
Mamy do wyboru wiele parametrów oraz możliwe że chcemy ostateczny obiekt mieć niezmienny (immutable).

3. Rozwiązanie:
A) budowniczy bandy czworga (Gang of Four)
Wzorzec konstruktora sugeruje wyodrębnienie kodu konstrukcji obiektu z jego własnej klasy
i przeniesienie go do oddzielnych obiektów zwanych konstruktorami.

B) Budowniczy metoda łańcuchowa :
Używamy statycznej wewnetrznej klasy (static inner class),
która ma za zadanie przekazać parametry do konstruktora naszej klasy.

4. Diagram klas wzorca Budowniczy:
A) wersja GoF (Gang of Four - bandy czworga):

B) wersja budowniczy metoda łańcuchowa (chaining):


5. Implementacja:
A) Budowniczy GoF
Kod operujący na wzorcu w celu uzyskania konkretnej klasy:
  1. public class Client {
  2.     public static void main (String[] args) {
  3.                 PizzaBuilder hawaiiPizzaBuilder = new HawaiiPizzaBuilder();
  4.                 Cook cook = new Cook(hawaiiPizzaBuilder);
  5.                 cook.buildPizza();
  6.                 Pizza hawaii = cook.getPizza();
  7.     }
  8. }
  9.  
Konkretna klasa którą chcemy uzyskąć:
  1. public class Pizza {
  2.         private String ciasto;
  3.         private String ser;
  4.         private String mieso;
  5.         private String warzywa;
  6.         private String owoce;
  7.         private String sos;
  8.         private String dodatki;
  9.        
  10.         public String getCiasto() {
  11.                 return ciasto;
  12.         }
  13.         public void setCiasto(String ciasto) {
  14.                 this.ciasto = ciasto;
  15.         }
  16.         public String getSer() {
  17.                 return ser;
  18.         }
  19.         public void setSer(String ser) {
  20.                 this.ser = ser;
  21.         }
  22.         public String getMieso() {
  23.                 return mieso;
  24.         }
  25.         public void setMieso(String mieso) {
  26.                 this.mieso = mieso;
  27.         }
  28.         public String getWarzywa() {
  29.                 return warzywa;
  30.         }
  31.         public void setWarzywa(String warzywa) {
  32.                 this.warzywa = warzywa;
  33.         }
  34.         public String getOwoce() {
  35.                 return owoce;
  36.         }
  37.         public void setOwoce(String owoce) {
  38.                 this.owoce = owoce;
  39.         }
  40.         public String getSos() {
  41.                 return sos;
  42.         }
  43.         public void setSos(String sos) {
  44.                 this.sos = sos;
  45.         }
  46.         public String getDodatki() {
  47.                 return dodatki;
  48.         }
  49.         public void setDodatki(String dodatki) {
  50.                 this.dodatki = dodatki;
  51.         }
  52. }
  53.  
Abstrakcyjna klasa budowniczego:
  1. public abstract class PizzaBuilder {
  2.     public Pizza getPizza () {
  3.         return pizza;
  4.     }
  5.  
  6.     private Pizza pizza =null;
  7.  
  8.     public HouseBuilder(){
  9.      pizza = new Pizza();
  10.    }
  11.     public abstract void dodajCiaso();
  12.     public abstract void dodajSer();
  13.     public abstract void dodajMieso();
  14.     public abstract void dodajWarzywa();
  15.     public abstract void dodajOwoce();
  16.     public abstract void dodajSos();
  17.     public abstract void dodajDodatki();
  18. }
  19.  
Konkretna klasa budownczego:
  1. public class HawaiiPizzaBuilder extends PizzaBuilder {
  2.     public void dodajCiaso() {
  3.                 getPizza().setCiasto("Cienkie");
  4.         };
  5.     public void dodajSer() {
  6.                 getPizza().setSer("Ementaler");
  7.         }
  8.     public void dodajMieso() {
  9.                 getPizza().setMieso("Szynka");         
  10.         }
  11.     public void dodajWarzywa() {};
  12.     public void dodajOwoce() {
  13.                 getPizza().setOwoce("Ananas");
  14.         }
  15.     public void dodajSos() {
  16.                 getPizza().setSos("przecier pomidorowy");
  17.         }
  18.     public void dodajDodatki() {
  19.                 getPizza().setDodatki("Bazylia i oregano");
  20.         };     
  21. }
  22.  
Director (kierownik) który zarządza obiektem budowniczego:
  1. public class Cook {
  2.     private PizzaBuilder pizzaBuilder;
  3.  
  4.     public void setHouseBuilder (PizzaBuilder pizzaBuilder) {
  5.         this.pizzaBuilder = pizzaBuilder;
  6.     }
  7.  
  8.     public void buildPizza() {
  9.         pizzaBuilder.dodajCiaso();
  10.         pizzaBuilder.dodajSer();
  11.         pizzaBuilder.dodajMieso();
  12.         pizzaBuilder.dodajWarzywa();
  13.         pizzaBuilder.dodajOwoce();
  14.         pizzaBuilder.dodajSos();
  15.         pizzaBuilder.dodajDodatki();
  16.     }
  17.  
  18.     public House getPizza(){
  19.         return pizzaBuilder.getPizza();
  20.     }
  21. }
  22.  


B) Budowniczy metoda łańcuchowa
Mamy klasę Pizza którą chcemy tworzyć, i aby była niezmienna (immutable):
  1. package pl.edu.java.designpatterns.builder;
  2.  
  3. public class Pizza {
  4.         private String ciasto;
  5.         private String ser;
  6.         private String mieso;
  7.         private String warzywa;
  8.         private String sos;
  9.         private String dodatki;
  10.        
  11.         public String getCiasto() {
  12.                 return ciasto;
  13.         }
  14.         public String getSer() {
  15.                 return ser;
  16.         }
  17.         public String getMieso() {
  18.                 return mieso;
  19.         }
  20.         public String getWarzywa() {
  21.                 return warzywa;
  22.         }
  23.         public String getSos() {
  24.                 return sos;
  25.         }
  26. }
  27.  
tworzymy naszego budowniczego wewnątrz klasy Pizza (wewnętrzna klasa):
  1. public class Pizza {
  2. .....
  3.         public static class Builder {
  4.                 private String ciasto;
  5.                 private String ser;
  6.                 private String mieso;
  7.                 private String warzywa;
  8.                 private String sos;
  9.  
  10.                 public Builder(String ciasto, String ser) {  // to są wymagane parametry
  11.                         this.ciasto = ciasto;
  12.                         this.ser = ser;
  13.                 }
  14.                
  15.                 public Builder mieso(String mieso) {
  16.                         this.mieso = mieso;
  17.                         return this;
  18.                 }
  19.                 public Builder warzywa(String warzywa) {
  20.                         this.warzywa = warzywa;
  21.                         return this;
  22.                 }
  23.                 public Builder sos(String sos) {
  24.                         this.sos = sos;
  25.                         return this;
  26.                 }
  27.                 public Pizza build() {
  28.                         return new Pizza(this);
  29.                 }
  30.         }
  31. ....
  32. }
  33.  
Konstruktor Builder(String ciasto, String ser) z tymi argumentami powoduje że mamy je obowiązkowe.
Jeżeli nie chcielibyśmy obowiązkowych parametrów to tworzymy konstruktor bezargumenowy:
public Builder() {}
i wszystkie parametry które możemy wybrać są opcjonalne.
Każda metoda której używamy w budowniczym zwraca this, co powoduje że możemy je użyć w jednym wywołaniu:
Pizza mojeZamowienie = new Pizza.Builder("Cienkie ciasto", "Ser gouda").mieso("Salami").warzywa("kukurydza").build();
i jeszcze pozostaje nam stworzenie konstruktora w klasie Pizza obsługującą budowniczego (Builder).
  1. public class Pizza {
  2. .....
  3.         public Pizza(Builder builder) {
  4.                 this.ciasto = builder.ciasto;  
  5.                 this.ser = builder.ser;
  6.                 this.mieso = builder.mieso;    
  7.                 this.warzywa = builder.warzywa;
  8.                 this.sos = builder.sos;
  9.         }
  10. ....
  11. }
  12.  
Zobaczmy ostateczną wersję klasy Pizza z budowniczym:
  1. package pl.edu.java.designpatterns.builder;
  2.  
  3. public class Pizza {
  4.         public static class Builder {
  5.                 private String ciasto;
  6.                 private String ser;
  7.                 private String mieso;
  8.                 private String warzywa;
  9.                 private String sos;
  10.  
  11.                 public Builder(String ciasto, String ser) {  // to są wymagane parametry
  12.                         this.ciasto = ciasto;
  13.                         this.ser = ser;
  14.                 }
  15.                
  16.                 public Builder mieso(String mieso) {
  17.                         this.mieso = mieso;
  18.                         return this;
  19.                 }
  20.                 public Builder warzywa(String warzywa) {
  21.                         this.warzywa = warzywa;
  22.                         return this;
  23.                 }
  24.                 public Builder sos(String sos) {
  25.                         this.sos = sos;
  26.                         return this;
  27.                 }
  28.                 public Pizza build() {
  29.                         return new Pizza(this);
  30.                 }
  31.         }
  32.        
  33.         private String ciasto;
  34.         private String ser;
  35.         private String mieso;
  36.         private String warzywa;
  37.         private String sos;
  38.         private String dodatki;
  39.        
  40.         public Pizza(Builder builder) {
  41.                 this.ciasto = builder.ciasto;  
  42.                 this.ser = builder.ser;
  43.                 this.mieso = builder.mieso;    
  44.                 this.warzywa = builder.warzywa;
  45.                 this.sos = builder.sos;
  46.         }
  47.  
  48.         public String getCiasto() {
  49.                 return ciasto;
  50.         }
  51.         public String getSer() {
  52.                 return ser;
  53.         }
  54.         public String getMieso() {
  55.                 return mieso;
  56.         }
  57.         public String getWarzywa() {
  58.                 return warzywa;
  59.         }
  60.         public String getSos() {
  61.                 return sos;
  62.         }
  63.        
  64.         public static void main(String[] args) {
  65.                 Pizza mojeZamowienie = new Pizza.Builder("Cienkie ciaso", "Ser Gouda").mieso("salami").warzywa("kukurydza").build();
  66.                
  67.                 System.out.println("Pizza 1:" + mojeZamowienie.getCiasto()
  68.                   + " " + mojeZamowienie.getSer()
  69.                   + " " + mojeZamowienie.getMieso()
  70.                   + " " + mojeZamowienie.getWarzywa()
  71.                   + " " + mojeZamowienie.getSos());
  72.                
  73.                 Pizza.Builder builder = new Pizza.Builder("Grube ciaso", "Ser Mozzarella");
  74.                 builder.mieso("szynka").sos("czosnkowy");
  75.                 Pizza drugaPizza = builder.build();
  76.  
  77.                 System.out.println("Pizza 2:" + drugaPizza.getCiasto()
  78.                   + " " + drugaPizza.getSer()
  79.                   + " " + drugaPizza.getMieso()
  80.                   + " " + drugaPizza.getWarzywa()
  81.                   + " " + drugaPizza.getSos());
  82.                
  83.         }
  84. }
  85.  
6. Zastosowanie w kodzie java:
- java.lang.StringBuilder#append() (unsynchronized)
- java.lang.StringBuffer#append() (synchronized)

  1.  StringBuilder builder = new StringBuilder();
  2.  builder.append("To jest moje równanie: ");
  3.  builder.append(2);
  4.  builder.append("+");
  5.  builder.append(8);
  6.  builder.append("=");
  7.  builder.append(10);
  8.  builder.append(".");
  9.  System.out.println(builder.toString());
  10.  
- Locale.Builder - Budowniczy metoda łańcuchowa
- java.nio.ByteBuffer#put() (również CharBuffer, ShortBuffer, IntBuffer, LongBuffer, FloatBuffer i DoubleBuffer)
- javax.swing.GroupLayout.Group#addComponent()
- wszystkie implementacje: java.lang.Appendable.
created by cv.java.org.pl © 2023 All Rights Reserved.