Java Design Pattern - Builder Pattern

업데이트:

Design Pattern

  • 과거의 소프트웨어 개발 과정에서 발견된 설계의 노하우를 축적하여 이름을 붙여, 이후에 재이용하기 좋은 형태로 특정의 규약을 묶어서 정리한 것이다.
  • 디자인 패턴은 알고리즘이 아니라 상황에 따라 자주 쓰이는 설계 방법을 정리한 코딩 방법론일 뿐이며 모든 상황의 해결책이 아니다.

Creational Patterns, 생성 패턴

  • 객체가 생성되는 방식을 중시하는 패턴이다.
  • 객체의 생성과 조합을 캡슐화하여 객체가 생성 혹은 수정되어도 전체 프로그램 구조에 영향을 받지 않도록 유연성을 제공한다.

Builder Pattern

  • 복잡한 객체를 생성하는 방법을 정의하는 클래스와 표현하는 방법을 정의하는 클래스를 별도로 분리하여, 서로 다른 표현이라도 이를 생성할 수 있는 동일한 절차를 제공하는 패턴이다.

Example

public interface Item {

  public String name();

  public Packing packing();

  public float price();

}
public abstract class Burger implements Item {

  @Override
  public Packing packing() {
    return new Wrapper();
  }

  @Override
  public abstract float price();

}
public class ChickenBurger extends Burger {

  @Override
  public float price() {
    return 50.5f;
  }

  @Override
  public String name() {
    return "Chicken Burger";
  }

}
public class VegBurger extends Burger {

  @Override
  public float price() {
    return 25.0f;
  }

  @Override
  public String name() {
    return "Veg Burger";
  }

}
public abstract class ColdDrink implements Item {

  @Override
  public Packing packing() {
    return new Bottle();
  }

  @Override
  public abstract float price();

}
public class Coke extends ColdDrink {

  @Override
  public float price() {
    return 30.0f;
  }

  @Override
  public String name() {
    return "Coke";
  }

}
public class Pepsi extends ColdDrink {

  @Override
  public float price() {
    return 35.0f;
  }

  @Override
  public String name() {
    return "Pepsi";
  }

}
public interface Packing {

  public String pack();

}
public class Bottle implements Packing {

  @Override
  public String pack() {
    return "Bottle";
  }

}
public class Wrapper implements Packing {

  @Override
  public String pack() {
    return "Wrapper";
  }

}
  • Paking, Burger, ColdDring를 상속받은 각각의 객체를 생성한다.
public class Meal {

  private List<Item> items = new ArrayList<Item>();

  public void addItem(Item item) {
    items.add(item);
  }

  public float getCost() {
    float cost = 0.0f;
    for (Item item : items) {
      cost += item.price();
    }
    return cost;
  }

  public void showItems() {
    for (Item item : items) {
      System.out.print("Item : " + item.name());
      System.out.print(", Packing : " + item.packing().pack());
      System.out.println(", Price : " + item.price());
    }
  }

}
public class MealBuilder {

  public Meal prepareVegMeal() {
    Meal meal = new Meal();
    meal.addItem(new VegBurger());
    meal.addItem(new Coke());
    return meal;
  }

  public Meal prepareNonVegMeal() {
    Meal meal = new Meal();
    meal.addItem(new ChickenBurger());
    meal.addItem(new Pepsi());
    return meal;
  }

}
  • 햄버거와 음료의 세트 메뉴를 정의하는 Meal 객체를 선언하고, Builder 패턴의 MealBuilder 객체를 생성하여 원하는 조합으로 객체를 생성한다.
public class CustomMealBuilder {

  private Meal meal = new Meal();

  public void addBurger(Burger burger) {
    this.meal.addItem(burger);
  }

  public void addColdDring(ColdDrink coldDring) {
    this.meal.addItem(coldDring);
  }

  public Meal build() {
    return meal;
  }

}
  • MealBuilder를 동적으로 생성하도록 CustomMealBuilder와 같은 구조로 Builder 객체를 생성 할 수 있다.
public class BuilderPatternMain {

  public static void main(String[] args) {
    MealBuilder mealBuilder = new MealBuilder();

    Meal vegMeal = mealBuilder.prepareVegMeal();
    System.out.println("Veg Meal");
    vegMeal.showItems();
    System.out.println("Total Cost: " + vegMeal.getCost());

    Meal nonVegMeal = mealBuilder.prepareNonVegMeal();
    System.out.println("Non-Veg Meal");
    nonVegMeal.showItems();
    System.out.println("Total Cost: " + nonVegMeal.getCost());
  }

}
  • MealBuilder 객체를 이용하여 원하는 햄버거와 음료 세트를 생성자 파라미터 구조와 상관 없이 생성이 가능하다.

Source

Sample Code는 여기에서 확인 가능합니다.

댓글남기기