解決問題:主要解決在軟件系統中,有時候面臨着"一個複雜對象"的創建工作,其通常由各個部分的子對象用一定的算法構成;由於需求的變化,這個複雜對象的各個部分經常面臨着劇烈的變化,但是將它們組合在一起的算法卻相對穩定
使用的場景:一些基本部件不會變,而其組合經常變化的時候。(有基本的元素進行隨機的組合)
應用實例:去肯德基,漢堡、可樂、薯條、炸雞翅等是不變的,而其組合是經常變化的,生成出所謂的"套餐"。
優點:1、建造者獨立,易擴展。2、便於控制細節風險。
缺點:1、產品必須有共同點,範圍有限制。2、如內部變化複雜,會有很多的建造類。
一:創建一個表示食物條目和食物包裝的接口
Item.java
public interface Item { public String name(); public Packing packing(); public float price(); }
Packing.java
public interface Packing { public String pack(); }
二:創建實現 Packing 接口的實體類
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"; } }
三:創建實現 Item 接口的抽象類,該類提供了默認的功能。
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(); }四:創建擴展了 Burger 和 ColdDrink 的實體類。創建實體類
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"; } }
五:創建一個 Meal 類,帶有上面定義的 Item 對象。
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){ //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 類,實際的 builder 類負責創建 Meal 對象。(用mealBuilder來創建對應的meal,這裏是實際的操作)
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; } }七:BuiderPatternDemo 使用 MealBuider 來演示建造者模式(Builder 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()); } }