반응형

Design Patterns - Builder Pattern


(원문 위치 : http://www.tutorialspoint.com/design_pattern/builder_pattern.htm )

빌더 패턴은 간단한 객체와 단계별 접근을 사용하여 복잡한 객체를 만든다. 이 형태의 디자인 패턴은 객체를 생성하는 최상의 방법중 하나를 제공하기 때문에 생성적 패턴에 포함된다.

Builder 클래스는 단계적으로 최종 객체를 만든다. 이 builder는 다른 객체에 독립적이다.

Implementation

여기서는 대표적인 음식이 버거와 시원한 음료인 페스트푸드점에 대한 비즈니스 케이스를 고려했다. 버거는 야채 또는 치킨버가가 될 수 있고 포장지로 싸여질 것이다. 찬음료는 코카콜라나 펩시가 될 수 있고 병에 포장될 것이다.

버거와 찬음료 같은 음식 아이템을 표현하는 Item interface를 생성할 것이고 Item interface와 음식 아이템의 포장을 표현하는 Packing interface를 구현하는 클래스를 구체화한다. 그리고 버거는 포장지에 포장되고 찬음료는 병으로 포장되는 것으로써 Packing interface를 구현하는 클래스를 구체화한다.

그리고 Item의 ArrayList를 갖는 Meal 클래스와 Item의 조합에 따른 다른 형태의 Meal 객체를 만들기 위한 MealBuilder를 생성한다. BuilderPatternDemo, demo클래스는 Meal을 만들기 위해 MealBuilder를 사용할 것이다.
Builder Pattern UML Diagram

Step 1

음식 Item과 포장을 표현하는 Item interface를 생성한다.

Item.java

public interface Item {
   public String name();
   public Packing packing();
   public float price();	
}

Packing.java

public interface Packing {
   public String pack();
}

Step 2

Packing interface를 구현하는 구체적인 클래스를 생성한다.

Wrapper.java

public class Wrapper implements Packing {

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

Bottle.java

public class Bottle implements Packing {

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

Step 3

기본적인 기능을 제공하는 item interface를 구현하는 추상 클래스를 생성한다.

Burger.java

public abstract class Burger implements Item {

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

   @Override
   public abstract float price();
}

ColdDrink.java

public abstract class ColdDrink implements Item {

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

	@Override
	public abstract float price();
}

Step 4

Burger와 ColdDrink 클래스를 확장하는 구체적 클래스를 생성한다.

VegBurger.java

public class VegBurger extends Burger {

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

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

ChickenBurger.java

public class ChickenBurger extends Burger {

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

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

Coke.java

public class Coke extends ColdDrink {

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

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

Pepsi.java

public class Pepsi extends ColdDrink {

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

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

Step 5

위에 정의된 Item객체를 갖는 Meal 클래스를 생성한다.

Meal.java

import java.util.ArrayList;
import java.util.List;

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());
      }		
   }	
}

Step 6

Meal객체를 생성하기 위한 책임이 있는 실제 builer 클래스인 MealBuilder 클래스를 생성한다.

MealBuilder.java

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;
   }
}

Step 7

BuilderPatternDemo는 builer pattern을 시연하기 위해 MealBuilder를 사용한다.

BuilderPatternDemo.java

public class BuilderPatternDemo {
   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("\n\nNon-Veg Meal");
      nonVegMeal.showItems();
      System.out.println("Total Cost: " + nonVegMeal.getCost());
   }
}

Step 8

결과를 확인한다.

Veg Meal
Item : Veg Burger, Packing : Wrapper, Price : 25.0
Item : Coke, Packing : Bottle, Price : 30.0
Total Cost: 55.0


Non-Veg Meal
Item : Chicken Burger, Packing : Wrapper, Price : 50.5
Item : Pepsi, Packing : Bottle, Price : 35.0
Total Cost: 85.5


반응형

+ Recent posts