این الگو برای ساخت اشیاء پیچیده (complex) با کمک اشیاء ساده (simple) با استفاده از یک روش مرحله به مرحله (step by step) طراحی شده است. . این نوع از الگوی طراحی تحت الگوی Creational می آید و یکی از بهترین راه های ایجاد اشیا را فراهم می نماید. 
سناریو : فرض کنید برای صرف غذا در یک رستوران دو نوع گوشت و دو نوع نوشیدنی وجود دارد. شما می توانید به دلخواه یک غذای گوشتی و همراه با آن یک نوشیدنی میل نمایید. هر غذای گوشتی را باید در یک بسته بندی و نوشیدنی ها را در یک بطری صرف نمایید. پس می توان دو نوع بسته بندی (Packing) با نام های Warpper و Bottle داشته باشیم. هر غذا (گوشتی یا نوشیدنی) را می توان یک قلم (Item) در نظر گرفت که خود یک لیستی از غذاها را شامل می شود. حال interface ها و کلاس هایی را که تا اینجا وجود دارند را تعریف می نماییم. 

نمودار دیاگرام کلاس ها را در زیر مشاهده می کنید. 
آموزش الگوی طراحی بیلدر (Builder)


ابتدا رابط Item را تعریف می نماییم. این رابط سه متد به نام های ()packing() ، name و ()price دارد. که به ترتیب برای نمایش نام، بسته بندی و قیمت یک آیتم (غذای گوشتی یا نوشیدنی) تعریف شده اند. 

package builder;

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

سپس رابط Packing را برای نوع بسته بندی که می تواند از نوع Bottle (برای نوشیدنی) و یا Wrapper (برای غذای گوشتی) باشد را تعریف کنید. همچنین کلاس های Bottle و Wrapper را که این رابط را پیاده سازی می کنند را به دنبال ان تعریف نمایید. 

// Packing interface 
package builder;

public interface Packing {

    public String pack();
}

// Bottle class 
package builder;

public class Bottle implements Packing {

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

// Wrapper class 
package builder;

public class Wrapper implements Packing {

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


حال کلاس های Burger و ColdDrink را تعریف می کنیم. این دو کلاس رابط Item را پیاده سازی می کنند. این دو کلاس متد packing از رابط Item را نیز پیاده سازی می نمایند. 

// Burger class
package builder;

public abstract class Burger implements Item {

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

// ColdDrink class
package builder;

public abstract class ColdDrink implements Item {
    
    @Override public Packing packing() {
        return new Bottle();
    }    
}

در ادامه باید کلاس های VegBurger و ChickenBurger را که هر کدام یک نوع غذای گوشتی به حساب می آیند تعریف کنیم. هر یک از این دو کلاس از کلاس Burger مشتق می شوند. باید متدهای ()name و ()price را که در رابط Item تعریف نموده ایم در این دو کلاس انها را پیاده سازی نماییم. 

// VegBurger class 
package builder;

public class VegBurger extends Burger {
    
    @Override public float price() {
        return 25.0f;
    }
    
    @Override public String name() {
        return "Veg Burger";
    }
}
// ChickenBurger class 
package builder;

public class ChickenBurger extends Burger {
    
    @Override public float price(){
        return 50.5f;
    }
    
    @Override public String name(){
        return "Chicken Burger";
   }
}

حال بایدکلاس های Pepsi و Coke را که هر کدام یک نوع نوشیدنی سرد محسوب می شوند تعریف کنیم. هر یک از این دو کلاس از کلاس ColdDrink مشتق می شوند. متدهای ()name و ()price را که در رابط Item تعریف شده اند را در این دو کلاس پیاده سازی نمایید. 

// Pepsi class 
package builder;

public class Pepsi extends ColdDrink {

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

   @Override public String name() {
      return "Pepsi";
   }
}
// Coke class 
package builder;

public class Coke extends ColdDrink {

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

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

برای راحتی کار دو نوع داده شمارشی به نام های BurgerType و ColdDrinkType برای انواع غذای گوشتی و نوشیدنی تعریف می نماییم. 

// BurgerType enum 
package builder;

public enum BurgerType {    
    chicken(1),
    veg(2);
        
    int id;
    private BurgerType(int id) {
        this.id = id;
    }
    public int getId() {
        return id;
    }    
}
// BurgerType enum 
package builder;

public enum ColdDrinkType {    
    pepsi(1),
    coke(2);        
    int id;

    private ColdDrinkType(int id) {
        this.id = id;
    }
    public int getId() {
        return id;
    }    
}

برای ثبت سفارشات یک مشتری کلاس Meal را تعریف کنید. این کلاس یک متد به نام ()addItem با آرگومانی از نوع رابط Item دارد که با فراخوانی آن می توان آیتم مورد نظر را به لیست سفارشات اضافه کرد. متغیر items برای ذخیره کردن لیست سفارشات تعریف شده است. همچنین دو متد ()getCost و ()showItems برای محاسبه هزینه و نمایش سفارشات در این کلاس تعریف شده اند. 

package builder;

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

حال باید کلاس MealBuilder را برای ساخت یک Meal تعریف نمایید. متدهای ()getBurger و ()getColdDrink با استفاده از مقدار آرگومانشان به ترتیب یک نمونه از غذای گوشتی و یک نوع نوشیدنی سرد را ایجاد میکنند. متد ()prepare دارای دو آرگومان می باشد که به ترتیب برای تعیین غذای گوشتی و نوشیدنی می باشند. 

package builder;

public class MealBuilder {

   public Meal prepare(BurgerType bType, ColdDrinkType cdType) {
      Meal meal = new Meal();
      
      Burger    burger    = getBurger(bType);
      ColdDrink coldDrink = getColdDrink(cdType);
      
      meal.addItem(burger);
      meal.addItem(coldDrink);
      return meal;
   }   
   
   private Burger getBurger(BurgerType type){
       switch(type){
          case chicken:   return new ChickenBurger();
          case veg:       return new VegBurger();
          default:        return new ChickenBurger(); // ChickenBurger is default
      }
   }
   
   private ColdDrink getColdDrink(ColdDrinkType type){
       switch(type){
          case pepsi:     return new Pepsi();
          case coke:      return new Coke();
          default:        return new Pepsi(); // Pepsi is default
      }
   }
}

سر انجام کلاس BuilderPatternDemo را برای نمایش عملکرد برنامه تعریف نمایید. با مشاهده کد ها به راحتی می توانید عملکرد آنها را در یابید. 

package builder;

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

      Meal vegMeal = mealBuilder.prepare(BurgerType.veg, ColdDrinkType.coke);
      System.out.println("Veg Meal");
      vegMeal.showItems();
      System.out.println("Total Cost: " + vegMeal.getCost());

      Meal nonVegMeal = mealBuilder.prepare(BurgerType.chicken, ColdDrinkType.pepsi);
      System.out.println("\n\nChicken Meal");
      nonVegMeal.showItems();
      System.out.println("Total Cost: " + nonVegMeal.getCost());
   }
}

امیدوارم این آموزش برای شما مفید باشد! 
برای کسب اطلاعات بیشتر به سایت tutorialspoint مراجعه نمایید. 
 منبع : javaworld.com
آیا این پاسخ به شما کمک کرد؟ 17 کاربر این را مفید یافتند (17 نظرات)