Budowniczy (Builder)

Budowniczy (Builder) to wzorzec projektowy należący do wzorców kreacyjnych. Został on stworzony w celu usprawnienia tworzenia skomplikowanych obiektów. Na końcu procesu tworzenia obiektu klient budowniczego otrzymuje gotowy produkt podobnie jak w przypadku fabryki abstrakcyjnej, jednak cały proces budowania w przypadku wzorca budowniczego składa się z kilku etapów. Plusem zastosowania tego wzorca jest możliwość budowy obiektów o dużym zróżnicowaniu w budowie wewnętrznej oraz to że cały proces budowy jest kontrolowany przez klienta klasy budowniczego.

Przykład zastosowania wzorca Builder:

Produktem wzorca builder jest klasa Building, w której skład wchodzą elemtnty: Roof, Tier oraz Basement.

  1. public interface Roof {
  2.     public String getDesign();
  3. }
  4. public class SlateRoof implements Roof {
  5.     public String getDesign() {
  6.         return "    / \\" + '\n' +
  7.                "   /   \\" + '\n' +
  8.                "  /     \\" + '\n' +
  9.                " /       \\" + '\n' +
  10.                "/         \\";
  11.     }
  12. }
  13. public class FlatRoof implements Roof {
  14.     public String getDesign() {
  15.         return "/---------\\";
  16.     }
  17. }
  18. public class Basement {
  19.     public String getDesign() {
  20.         return "_xxxxxxxxx_";
  21.     }
  22. }
  23. public class Tier {
  24.     public String getDesign() {
  25.         return " | o o o |";
  26.     }
  27. }
  28. public class Building {
  29.     private Roof roof;
  30.     private List  tiers;
  31.     private Basement basement;
  32.     public Basement getBasement() {
  33.         return basement;
  34.     }
  35.     public void setBasement(Basement basement) {
  36.         this.basement = basement;
  37.     }
  38.     public Roof getRoof() {
  39.         return roof;
  40.     }
  41.     public void setRoof(Roof roof) {
  42.         this.roof = roof;
  43.     }
  44.     public List getTiers() {
  45.         return tiers;
  46.     }
  47.     public void setTiers(List tiers) {
  48.         this.tiers = tiers;
  49.     }
  50.     public String getDesign() {
  51.         String design = roof.getDesign()+'\n';
  52.         for (Tier tier : tiers) {
  53.             design += tier.getDesign()+'\n';
  54.         }
  55.         design += basement.getDesign()+'\n';
  56.         return design;
  57.     }
  58. }

Klasa AbstractBuildingBuilder jest przykładem wzorca Budowniczego (Builder). Definiuje ona metody, które są niezbędne w procesie produkcji klasy Building. Klasa zawiera referencję do obiektu klasy Building oraz metody pozwalające na utworzenie nowego obiektu klasy Building oraz pobranie jego referencji.

  1. public abstract class AbstractBuildingBuilder {
  2.     Building building;
  3.     public void createBuilding() {
  4.         building = new Building();
  5.     }
  6.     public Building getBuilding() {
  7.         return building;
  8.     }
  9.     public abstract void buildTiers();
  10.     public abstract void buildRoof();
  11.     public abstract void buildBasement();
  12. }
Implementacja klasy AbstractBuildingBuilder.
  1. public class BobBuilder extends AbstractBuildingBuilder {
  2.     private static int TIERS = 5;
  3.     @Override
  4.     public void buildTiers() {
  5.         List tiers = new ArrayList();
  6.         for (int i = 0; i < TIERS; i++) {
  7.             tiers.add(new Tier());
  8.         }
  9.         getBuilding().setTiers(tiers);
  10.     }
  11.     @Override
  12.     public void buildRoof() {
  13.         getBuilding().setRoof(new FlatRoof());
  14.     }
  15.     @Override
  16.     public void buildBasement() {
  17.         getBuilding().setBasement(new Basement());
  18.     }
  19. }
Kolejna implementacja klasy AbstractBuildingBuilder.
  1. public class SlateBuilder extends AbstractBuildingBuilder {
  2.     @Override
  3.     public void buildTiers() {
  4.         List tiers = new ArrayList();
  5.         tiers.add(new Tier());
  6.         tiers.add(new Tier());
  7.         getBuilding().setTiers(tiers);
  8.     }
  9.     @Override
  10.     public void buildRoof() {
  11.         getBuilding().setRoof(new SlateRoof());
  12.     }
  13.     @Override
  14.     public void buildBasement() {
  15.         getBuilding().setBasement(new Basement());
  16.     }
  17. }
Klasa odpowiedzialna za zarządzanie obiektem wzorca budowniczego.
  1. public class ConstructionDirector {
  2.     private AbstractBuildingBuilder abb;
  3.     public void setBuilder(AbstractBuildingBuilder abb) {
  4.         this.abb = abb;
  5.     }
  6.     public Building getBuilding() {
  7.         return abb.getBuilding();
  8.     }
  9.     public void constructBuilding() {
  10.         abb.createBuilding();
  11.         abb.buildRoof();
  12.         abb.buildBasement();
  13.         abb.buildTiers();
  14.     }
  15. }
Przykład użycia wzorca Budowniczego implementowanego przez klasy BobBuilder oraz SlateBuilder.
  1. public class Main {
  2.     public static void main(String[] arg) {
  3.         ConstructionDirector director = new ConstructionDirector();
  4.         AbstractBuildingBuilder bob = new BobBuilder();
  5.         director.setBuilder(bob);
  6.         director.constructBuilding();
  7.         Building building = director.getBuilding();
  8.         System.out.println("BobBuilder build: ");
  9.         System.out.println(building.getDesign());
  10.         AbstractBuildingBuilder slate = new SlateBuilder();
  11.         director.setBuilder(slate);
  12.         director.constructBuilding();
  13.         building = director.getBuilding();
  14.         System.out.println("SlateBuilder build: ");
  15.         System.out.println(building.getDesign());
  16.     }
  17. }
Wynik działania klasy Main:
  1. BobBuilder build:
  2. /---------\
  3.  | o o o |
  4.  | o o o |
  5.  | o o o |
  6.  | o o o |
  7.  | o o o |
  8. _xxxxxxxxx_
  9. SlateBuilder build:
  10.     / \
  11.    /   \
  12.   /     \
  13.  /       \
  14. /         \
  15.  | o o o |
  16.  | o o o |
  17. _xxxxxxxxx_

 

Komentarze

Dodaj nowy komentarz

  • Adresy internetowe są automatycznie zamieniane w odnośniki, które można kliknąć.
  • Dozwolone znaczniki HTML: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Znaki końca linii i akapitu dodawane są automatycznie.

Więcej informacji na temat formatowania

CAPTCHA
Jakie znaki widnieją na obrazku?
Image CAPTCHA
Przepisz ciąg znaków z obrazka.