一、模式簡介
定義:將一個復雜對象的構造與它的表示分離,使同樣的構建過程可以創建不同的表示,它是將一個復雜的對象分解為多個簡單的對象,然后一步一步構建而成。它將變與不變相分離,即產品的組成部分是不變的,但每一部分是可以靈活選擇的。
場景:創建的對象較復雜,由多個部件構成,各部件面臨著復雜的變化,但構件間的建造順序是穩定的。創建復雜對象的算法獨立于該對象的組成部分以及它們的裝配方式,即產品的構建過程和最終的表示是獨立的。
- 角色結構:
- 產品角色(Product):它是包含多個組成部件的復雜對象,由具體建造者來創建其各個滅部件。
- 抽象建造者(Builder):它是一個包含創建產品各個子部件的抽象方法的接口,通常還包含一個返回復雜產品的方法。
- 具體建造者(Concrete Builder):實現 Builder 接口,完成復雜產品的各個部件的具體創建方法。
- 指揮官(Director):它調用建造者對象中的部件構造與裝配方法完成復雜對象的創建,在指揮者中不涉及具體產品的信息。
二、經典模式實現
定義食品屬性接口、抽象食品屬性類、具體食品屬性類
public interface Food { -> 產品角色
String name(); -> 名稱
Double price(); -> 價格
Pack pack(); -> 包裝
}
public abstract class AbstractHamburg implements Food { -> 抽象建造者
@Override
public abstract String name();
@Override
public abstract Double price();
@Override
public Pack pack() {
return new Paper();
}
}
public class ChickenHamburg extends AbstractHamburg { -> 具體建造者
@Override
public String name() {
return "炸雞漢堡";
}
@Override
public Double price() {
return 15.00;
}
}
public abstract class AbstractCoke implements Food { -> 抽象建造者
@Override
public abstract String name();
@Override
public abstract Double price();
@Override
public Pack pack() {
return new Bottle();
}
}
public class CocaCola extends AbstractCoke { -> 具體建造者
@Override
public String name() {
return "可口可樂";
}
@Override
public Double price() {
return 5.00;
}
}
public class PepsiCola extends AbstractCoke { -> 具體建造者
@Override
public String name() {
return "百事可樂";
}
@Override
public Double price() {
return 5.00;
}
}
定義食品包裝接口、具體包裝實現類
public interface Pack { -> 抽象建造者
String pack();
}
public class Bottle implements Pack { -> 具體建造者
@Override
public String pack() {
return "瓶裝";
}
}
public class Paper implements Pack { -> 具體建造者
@Override
public String pack() {
return "紙裝";
}
}
定義套餐選擇方式
public class Meal {
private List<Food> list = new ArrayList<>();
public boolean addFood(Food food) {
return list.add(food);
}
public boolean removeFood(Food food) {
return list.remove(food);
}
public Double price() {
BigDecimal decimal = BigDecimal.ZERO;
for (int i = 0; i < list.size(); i++) {
decimal = decimal.add(BigDecimal.valueOf(list.get(i).price()));
}
return decimal.doubleValue();
}
public void display() {
for (int i = 0; i < list.size(); i++) {
Food food = list.get(i);
System.out.println(food.pack().pack() + " " + food.name() + " " + food.price());
}
}
}
public class MealBuilder { -> 指揮官
public Meal ChickenCoca() {
Meal meal = new Meal();
meal.addFood(new ChickenHamburg());
meal.addFood(new CocaCola());
return meal;
}
public Meal ChickenPepsi() {
Meal meal = new Meal();
meal.addFood(new ChickenHamburg());
meal.addFood(new PepsiCola());
return meal;
}
}
選擇套餐
MealBuilder builder = new MealBuilder();
Meal mealChickenCoca = builder.ChickenCoca();
mealChickenCoca.display();
Meal mealChickenPepsi = builder.ChickenPepsi();
mealChickenPepsi.display();
三、變種模式實現
套餐構造方法設置私有,通過內部提供的構造器完成實例化
public class Meal {
private List<Food> list = new ArrayList<>();
public Double price() {
BigDecimal decimal = BigDecimal.ZERO;
for (int i = 0; i < list.size(); i++) {
decimal = decimal.add(BigDecimal.valueOf(list.get(i).price()));
}
return decimal.doubleValue();
}
public void display() {
for (int i = 0; i < list.size(); i++) {
Food food = list.get(i);
System.out.println(food.pack().pack() + " " + food.name() + " " + food.price());
}
}
private Meal(MealBuilder builder) {
if(builder.list != null){
this.list = builder.list;
}
}
public static class MealBuilder {
private List<Food> list = new ArrayList<>();
public MealBuilder CocaCola() {
list.add(new CocaCola());
return this;
}
public MealBuilder PepsiCola() {
list.add(new PepsiCola());
return this;
}
public MealBuilder ChickenHamburg() {
list.add(new ChickenHamburg());
return this;
}
public Meal build() {
return new Meal(this);
}
}
}
選擇套餐
Meal.MealBuilder builder = new Meal.MealBuilder();
Meal meal = builder.CocaCola().PepsiCola().ChickenHamburg().build();
meal.display();