빌더 패턴

출처: Springframework Guru - Builder pattern, Refactoring Guru - Builder pattern
🚫 아래 내용은 주관적인 생각이므로 사실과 다를 수 있습니다.

Builder Pattern
(빌더 패턴)

생성 패턴(Object Creational)

객체를 생성하는 빌더를 Director에 주입해서 객체를 생성하는 패턴이다.

주로 복잡한 객체를 생성할 때 사용하는 패턴으로
객체 생성에 필요한 값들을 빼먹거나 순서를 바꿔서 전달할 걱정을 안해도 된다.

Class diagram

클래스_다이어그램

예시

// Object - 생성할 객체
public class House {
    private String floor;
    private String wall;
    private String roof;
    private boolean painted;

    public void setFloor(String floor) {
        this.floor = floor;
    }

    public void setWall(String wall) {
        this.wall = wall;
    }

    public void setRoof(String roof) {
        this.roof = roof;
    }

    public void setPainted(boolean painted) {
        this.painted = painted;
    }

    @Override
    public String toString() {
        return "Floor - " + floor
             + " Wall - " + wall
             + " Roof - " + roof
             + " Is Painted? " + painted;
    }
}
// Builder Interface - 객체의 필드를 할당하고 생성된 객체를 반환하는 인터페이스
public interface HouseBuilder {
    void buildFloor();
    void buildWall();
    void buildRoof();
    void paintHouse();
    House getHouse();
}
// Builder - 빌더 인터페이스의 구현체
public class ConcreteHouseBuilder implements HouseBuilder{
    private House house;
    
    public ConcreteHouseBuilder() {
        this.house = new House();
    }
    
    @Override
    public void buildFloor() {
        house.setFloor("Concrete, brick, and stone");
        System.out.println("ConcreteHouseBuilder: Floor complete...");
    }
    
    @Override
    public void buildWall(){
      house.setWall("Concrete, mortar, brick, and reinforced steel");
      System.out.println("ConcreteHouseBuilder: Wall complete...");
    }
    
    @Override
    public void buildRoof(){
      house.setRoof("Concrete and reinforced steel");
        System.out.println("ConcreteHouseBuilder: Roof complete...");
    }
    
    @Override
    public void paintHouse(){
      house.setPainted(true);
        System.out.println("ConcreteHouseBuilder: Painting complete...");
    }

    public House getHouse() {
        System.out.println("ConcreteHouseBuilder: Concrete house complete...");
        return this.house;
    }
}
// Director - 빌더를 주입받아 객체를 생성하는 클래스
public class ConstructionEngineer {
    private HouseBuilder houseBuilder;

    public ConstructionEngineer(HouseBuilder houseBuilder){
        this.houseBuilder = houseBuilder;
    }
    
    public House constructHouse() {
        this.houseBuilder.buildFloor();
        this.houseBuilder.buildWall();
        this.houseBuilder.buildRoof();
        this.houseBuilder.paintHouse();
        return this.houseBuilder.getHouse();
    }
}
// Test
public class ConstructionEngineerTest {
    @Test
    public void testConstructHouse() throws Exception {
        HouseBuilder concreteHouseBuilder = new ConcreteHouseBuilder();
        ConstructionEngineer engineerA = new ConstructionEngineer(concreteHouseBuilder);
        House houseA = engineerA.constructHouse();
        System.out.println("House is: " + houseA);

        // 빌더만 교체하면 간단히 다른 객체를 생성할 수 있다.
        PrefabricatedHouseBuilder prefabricatedHouseBuilder = new PrefabricatedHouseBuilder();
        ConstructionEngineer engineerB = new ConstructionEngineer(prefabricatedHouseBuilder);
        House houseB = engineerB.constructHouse();
        System.out.println("House is: " + houseB);
    }
}

장점

  • 객체를 생성하는 단계를 분할해, 생략하거나 순차적으로나 재귀적으로도 생성할 수 있다.
  • 생성 과정을 재활용해 다양한 객체를 쉽게 생성할 수 있다.
  • SOLID - [S]단일책임원칙: 복잡한 생성 코드를 비지니스 로직에서 분리할 수 있다.

단점

  • 빌더 패턴을 위해 다수의 새 클래스를 생성해야하기 때문에 전반적인 코드의 복잡도가 높아진다.

댓글남기기