构建器模式表示“使用逐步的方法从简单对象构建复杂对象”

当对象不能一步创建时,通常使用此模式,例如在反序列化复杂对象时。

构建器设计模式的优点

构建器模式的主要优点如下:

  • 它提供了对象构建和表示之间的明确分离。
  • 它对构建过程提供了更好的控制。
  • 它支持更改对象的内部表示。

构建器模式的 UML 示例

5-1.jpg

构建器设计模式示例

要创建构建器设计模式的简单示例,你需要遵循以下6个步骤。

  1. 创建 Packing 接口
  2. 创建两个抽象类 CD 和 Company
  3. 创建 Company 的两个实现类:Sony 和 Samsung
  4. 创建 CDType 类
  5. 创建 CDBuilder 类
  6. 创建 BuilderDemo 类

1) 创建 Packing 接口

文件:Packing.java

public interface Packing { 
    public String pack(); 
    public int price(); 
}

2) 创建两个抽象类 CD 和 Company

创建一个实现 Packing 接口的抽象类 CD。

文件:CD.java

public abstract class CD implements Packing { 
    public abstract String pack(); 
}

文件:Company.java

public abstract class Company extends CD { 
    public abstract int price(); 
}

3) 创建 Company 的两个实现类:Sony 和 Samsung

文件:Sony.java

public class Sony extends Company { 
    @Override 
    public int price() {  
        return 20; 
    } 
    @Override 
    public String pack() { 
        return "Sony CD"; 
    }     
} // Sony 类结束

文件:Samsung.java

public class Samsung extends Company { 
    @Override 
    public int price() {  
        return 15; 
    } 
    @Override 
    public String pack() { 
        return "Samsung CD"; 
    }     
} // Samsung 类结束

4) 创建 CDType 类

文件:CDType.java

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

public class CDType { 
    private List<Packing> items = new ArrayList<Packing>(); 

    public void addItem(Packing packs) {  
        items.add(packs); 
    } 

    public void getCost() { 
        for (Packing packs : items) { 
            packs.price(); 
        }  
    } 

    public void showItems() { 
        for (Packing packing : items) { 
            System.out.print("CD name : " + packing.pack()); 
            System.out.println(", Price : " + packing.price()); 
        }    
    }   
} // CDType 类结束

5) 创建 CDBuilder 类

文件:CDBuilder.java

public class CDBuilder { 
    public CDType buildSonyCD() {  
        CDType cds = new CDType(); 
        cds.addItem(new Sony()); 
        return cds; 
    } 

    public CDType buildSamsungCD() { 
        CDType cds = new CDType(); 
        cds.addItem(new Samsung()); 
        return cds; 
    } 
} // CDBuilder 类结束

6) 创建 BuilderDemo 类

文件:BuilderDemo.java

public class BuilderDemo { 
    public static void main(String args[]) { 
        CDBuilder cdBuilder = new CDBuilder(); 

        CDType cdType1 = cdBuilder.buildSonyCD(); 
        cdType1.showItems(); 

        CDType cdType2 = cdBuilder.buildSamsungCD(); 
        cdType2.showItems(); 
    } 
}

上述示例的输出

  1. CD name : Sony CD, Price : 20
  2. CD name : Samsung CD, Price : 15

构建器模式的另一个实际示例

构建器模式的 UML:

我们考虑一个必胜客的业务案例,在这里我们可以得到不同种类的比萨和冷饮。

比萨可以是素食比萨或非素食比萨中的几种类型(如奶酪比萨、洋葱比萨、香料比萨等),并且有四种尺寸:小、中、大、超大。

冷饮可以有几种类型(如百事可乐、可口可乐、雪碧、芬达、芒果汁、菊花茶等),并且有三种尺寸:小、中、大。

5-2.jpg

构建器模式的实际示例

让我们一步步看看构建器设计模式的实际示例。

步骤 1:创建表示比萨和冷饮的接口 Item。

文件:Item.java

public interface Item { 
    public String name(); 
    public String size(); 
    public float price(); 
} // Item 接口结束

步骤 2:创建实现 Item 接口的抽象类 Pizza。

文件:Pizza.java

public abstract class Pizza implements Item { 
    @Override 
    public abstract float price(); 
} // Pizza 抽象类结束

步骤 3:创建实现 Item 接口的抽象类 ColdDrink。

文件:ColdDrink.java

public abstract class ColdDrink implements Item { 
    @Override 
    public abstract float price(); 
} // ColdDrink 抽象类结束

步骤 4:创建扩展 Pizza 抽象类的抽象类 VegPizza。

文件:VegPizza.java

public abstract class VegPizza extends Pizza { 
    @Override 
    public abstract float price(); 
    @Override 
    public abstract String name(); 
    @Override 
    public abstract String size(); 
} // VegPizza 抽象类结束

步骤 5:创建扩展 Pizza 抽象类的抽象类 NonVegPizza。

文件:NonVegPizza.java

public abstract class NonVegPizza extends Pizza { 
    @Override 
    public abstract float price(); 
    @Override 
    public abstract String name(); 
    @Override 
    public abstract String size(); 
} // NonVegPizza 抽象类结束

步骤 6:现在,创建扩展 VegPizza 抽象类的具体子类 SmallCheezePizza、MediumCheezePizza、LargeCheezePizza 和 ExtraLargeCheezePizza。

文件:SmallCheezePizza.java

public class SmallCheezePizza extends VegPizza { 
    @Override 
    public float price() { 
        return 170.0f; 
    } 
    @Override 
    public String name() { 
        return "Cheeze Pizza"; 
    } 
    @Override 
    public String size() { 
        return "Small size"; 
    }  
} // SmallCheezePizza 类结束

文件:MediumCheezePizza.java

public class MediumCheezePizza extends VegPizza { 
    @Override 
    public float price() { 
        return 220.f; 
    } 
    @Override 
    public String name() { 
        return "Cheeze Pizza"; 
    } 
    @Override 
    public String size() { 
        return "Medium Size"; 
    } 
} // MediumCheezePizza 类结束

文件:LargeCheezePizza.java

public class LargeCheezePizza extends VegPizza { 
    @Override 
    public float price() { 
        return 260.0f; 
    } 
    @Override 
    public String name() { 
        return "Cheeze Pizza"; 
    } 
    @Override 
    public String size() { 
        return "Large Size"; 
    } 
} // LargeCheezePizza 类结束

文件:ExtraLargeCheezePizza.java

public class ExtraLargeCheezePizza extends VegPizza { 
    @Override 
    public float price() { 
        return 300.f; 
    } 
    @Override 
    public String name() { 
        return "Cheeze Pizza"; 
    } 
    @Override 
    public String size() { 
        return "Extra-Large Size"; 
    } 
} // ExtraLargeCheezePizza 类结束

步骤 7:同样地,创建扩展 VegPizza 抽象类的具体子类 SmallOnionPizza、MediumOnionPizza、LargeOnionPizza 和 ExtraLargeOnionPizza。

文件:SmallOnionPizza.java

public class SmallOnionPizza extends VegPizza { 
    @Override 
    public float price() { 
        return 120.0f; 
    } 
    @Override 
    public String name() { 
        return "Onion Pizza"; 
    } 
    @Override 
    public String size() { 
        return "Small Size"; 
    }  
} // SmallOnionPizza 类结束

文件:MediumOnionPizza.java

public class MediumOnionPizza extends VegPizza { 
    @Override 
    public float price() { 
        return 150.0f; 
    } 
    @Override 
    public String name() { 
        return "Onion Pizza"; 
    } 
    @Override 
    public String size() { 
        return "Medium Size"; 
    }  
} // MediumOnionPizza 类结束

文件:LargeOnionPizza.java

public class LargeOnionPizza extends VegPizza { 
    @Override 
    public float price() { 
        return 180.0f; 
    } 
    @Override 
    public String name() { 
        return "Onion Pizza"; 
    } 
    @Override 
    public String size() { 
        return "Large Size"; 
    } 
} // LargeOnionPizza 类结束

文件:ExtraLargeOnionPizza.java

public class ExtraLargeOnionPizza extends VegPizza { 
    @Override 
    public float price() { 
        return 200.0f; 
    } 
    @Override 
    public String name() { 
        return "Onion Pizza"; 
    } 
    @Override 
    public String size() { 
        return "Extra-Large Size"; 
    } 
} // ExtraLargeOnionPizza 类结束

步骤 8:同样地,创建扩展 VegPizza 抽象类的具体子类 SmallMasalaPizza、MediumMasalaPizza、LargeMasalaPizza 和 ExtraLargeMasalaPizza。

文件:SmallMasalaPizza.java

public class SmallMasalaPizza extends VegPizza { 
    @Override 
    public float price() { 
        return 100.0f; 
    } 
    @Override 
    public String name() { 
        return "Masala Pizza"; 
    } 
    @Override 
    public String size() { 
        return "Small Size"; 
    } 
} // SmallMasalaPizza 类结束

文件:MediumMasalaPizza.java

public class MediumMasalaPizza extends VegPizza { 
    @Override 
    public float price() { 
        return 120.0f; 
    } 
    @Override 
    public String name() { 
        return "Masala Pizza"; 
    } 
    @Override 
    public String size() { 
        return "Medium Size"; 
    } 
} // MediumMasalaPizza 类结束

文件:LargeMasalaPizza.java

public class LargeMasalaPizza extends VegPizza { 
    @Override 
    public float price() { 
        return 150.0f; 
    } 
    @Override 
    public String name() { 
        return "Masala Pizza"; 
    } 
    @Override 
    public String size() { 
        return "Large Size"; 
    } 
} // LargeMasalaPizza 类结束

文件:ExtraLargeMasalaPizza.java

public class ExtraLargeMasalaPizza extends VegPizza { 
    @Override 
    public float price() { 
        return 180.0f; 
    } 
    @Override 
    public String name() { 
        return "Masala Pizza"; 
    } 
    @Override 
    public String size() { 
        return "Extra-Large Size"; 
    } 
} // ExtraLargeMasalaPizza 类结束

步骤 9:现在,创建扩展 NonVegPizza 抽象类的具体子类 SmallNonVegPizza、MediumNonVegPizza、LargeNonVegPizza 和 ExtraLargeNonVegPizza。

文件:SmallNonVegPizza.java

public class SmallNonVegPizza extends NonVegPizza { 
    @Override 
    public float price() { 
        return 180.0f; 
    } 
    @Override 
    public String name() { 
        return "Non-Veg Pizza"; 
    } 
    @Override 
    public String size() { 
        return "Small Size"; 
    } 
} // SmallNonVegPizza 类结束

文件:MediumNonVegPizza.java

public class MediumNonVegPizza extends NonVegPizza { 
    @Override 
    public float price() { 
        return 200.0f; 
    } 
    @Override 
    public String name() { 
        return "Non-Veg Pizza"; 
    } 
    @Override 
    public String size() { 
        return "Medium Size"; 
    } 
} // MediumNonVegPizza 类结束

文件:LargeNonVegPizza.java

public class LargeNonVegPizza extends NonVegPizza { 
    @Override 
    public float price() { 
        return 220.0f; 
    } 
    @Override 
    public String name() { 
        return "Non-Veg Pizza"; 
    } 
    @Override 
    public String size() { 
        return "Large Size"; 
    } 
} // LargeNonVegPizza 类结束

文件:ExtraLargeNonVegPizza.java

public class ExtraLargeNonVegPizza extends NonVegPizza { 
    @Override 
    public float price() { 
        return 250.0f; 
    } 
    @Override 
    public String name() { 
        return "Non-Veg Pizza"; 
    } 
    @Override 
    public String size() { 
        return "Extra-Large Size"; 
    } 
} // ExtraLargeNonVegPizza 类结束

步骤 10:现在,创建两个抽象类 Pepsi 和 Coke,它们将扩展 ColdDrink 抽象类。

文件:Pepsi.java

public abstract class Pepsi extends ColdDrink { 
    @Override 
    public abstract String name(); 
    @Override 
    public abstract String size(); 
    @Override 
    public abstract float price();  
} // Pepsi 类结束

文件:Coke.java

public abstract class Coke extends ColdDrink { 
    @Override 
    public abstract String name(); 
    @Override 
    public abstract String size(); 
    @Override 
    public abstract float price();  
} // Coke 类结束

步骤 11:创建扩展 Pepsi 抽象类的具体子类 SmallPepsi、MediumPepsi 和 LargePepsi。

文件:SmallPepsi.java

public class SmallPepsi extends Pepsi { 
    @Override 
    public String name() { 
        return "300 ml Pepsi"; 
    } 
    @Override 
    public float price() { 
        return 25.0f; 
    } 
    @Override 
    public String size() { 
        return "Small Size"; 
    }   
} // SmallPepsi 类结束

文件:MediumPepsi.java

public class MediumPepsi extends Pepsi { 
    @Override 
    public String name() { 
        return "500 ml Pepsi"; 
    } 
    @Override 
    public String size() { 
        return "Medium Size"; 
    } 
    @Override 
    public float price() { 
        return 35.0f; 
    }   
} // MediumPepsi 类结束

文件:LargePepsi.java

public class LargePepsi extends Pepsi { 
    @Override 
    public String name() { 
        return "750 ml Pepsi"; 
    } 
    @Override 
    public String size() { 
        return "Large Size"; 
    } 
    @Override 
    public float price() { 
        return 50.0f; 
    } 
} // LargePepsi 类结束

步骤 12:创建扩展 Coke 抽象类的具体子类 SmallCoke、MediumCoke 和 LargeCoke。

文件:SmallCoke.java

public class SmallCoke extends Coke { 
    @Override 
    public String name() { 
        return "300 ml Coke";  
    } 
    @Override 
    public String size() { 
        return "Small Size"; 
    } 
    @Override 
    public float price() { 
        return 25.0f; 
    } 
} // SmallCoke 类结束

文件:MediumCoke.java

public class MediumCoke extends Coke { 
    @Override 
    public String name() { 
        return "500 ml Coke";  
    } 
    @Override 
    public String size() { 
        return "Medium Size"; 
    } 
    @Override 
    public float price() { 
        return 35.0f; 
    } 
} // MediumCoke 类结束

文件:LargeCoke.java

public class LargeCoke extends Coke { 
    @Override 
    public String name() { 
        return "750 ml Coke";  
    } 
    @Override 
    public String size() { 
        return "Large Size"; 
    } 
    @Override 
    public float price() { 
        return 50.0f; 
    } 
} // LargeCoke 类结束

步骤 13:创建包含上述 Item 对象的 OrderedItems 类。

文件:OrderedItems.java

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

public class OrderedItems { 
    List<Item> items = new ArrayList<Item>(); 

    public void addItems(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.println("Item is: " + item.name()); 
            System.out.println("Size is: " + item.size()); 
            System.out.println("Price is: " + item.price()); 
        } 
    } 
} // OrderedItems 类结束

步骤 14:创建 OrderBuilder 类,它将负责创建 OrderedItems 类的对象。

文件:OrderBuilder.java

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 

public class OrderBuilder { 
    public OrderedItems preparePizza() throws IOException { 
        OrderedItems itemsOrder = new OrderedItems(); 
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 

        System.out.println("请输入比萨的选择:"); 
        System.out.println("============================"); 
        System.out.println("    1. 素食比萨    "); 
        System.out.println("    2. 非素食比萨  "); 
        System.out.println("    3. 退出      "); 
        System.out.println("============================"); 

        int pizzaandcolddrinkchoice = Integer.parseInt(br.readLine()); 
        switch (pizzaandcolddrinkchoice) { 
            case 1: { 
                System.out.println("您选择了素食比萨"); 
                System.out.println("\n\n"); 
                System.out.println("请输入素食比萨的类型:"); 
                System.out.println("------------------------------"); 
                System.out.println("    1. 奶酪比萨    "); 
                System.out.println("    2. 洋葱比萨    "); 
                System.out.println("    3. 香料比萨    "); 
                System.out.println("    4. 退出      "); 
                System.out.println("------------------------------"); 

                int vegpizzachoice = Integer.parseInt(br.readLine()); 
                switch (vegpizzachoice) { 
                    case 1: { 
                        System.out.println("您选择了奶酪比萨"); 
                        System.out.println("请输入奶酪比萨的大小:"); 
                        System.out.println("------------------------------------"); 
                        System.out.println("  1. 小奶酪比萨 "); 
                        System.out.println("  2. 中奶酪比萨 "); 
                        System.out.println("  3. 大奶酪比萨 "); 
                        System.out.println("  4. 超大奶酪比萨 "); 
                        System.out.println("------------------------------------"); 

                        int cheezepizzasize = Integer.parseInt(br.readLine()); 
                        switch (cheezepizzasize) { 
                            case 1: 
                                itemsOrder.addItems(new SmallCheezePizza()); 
                                break; 
                            case 2: 
                                itemsOrder.addItems(new MediumCheezePizza()); 
                                break;  
                            case 3: 
                                itemsOrder.addItems(new LargeCheezePizza()); 
                                break;  
                            case 4: 
                                itemsOrder.addItems(new ExtraLargeCheezePizza()); 
                                break;   
                        } 
                    } 
                    break; 
                    case 2: { 
                        System.out.println("您选择了洋葱比萨"); 
                        System.out.println("请输入洋葱比萨的大小:"); 
                        System.out.println("----------------------------------"); 
                        System.out.println("  1. 小洋葱比萨 "); 
                        System.out.println("  2. 中洋葱比萨 "); 
                        System.out.println("  3. 大洋葱比萨 "); 
                        System.out.println("  4. 超大洋葱比萨 "); 
                        System.out.println("----------------------------------"); 

                        int onionpizzasize = Integer.parseInt(br.readLine()); 
                        switch (onionpizzasize) { 
                            case 1: 
                                itemsOrder.addItems(new SmallOnionPizza()); 
                                break; 
                            case 2: 
                                itemsOrder.addItems(new MediumOnionPizza()); 
                                break;  
                            case 3: 
                                itemsOrder.addItems(new LargeOnionPizza()); 
                                break;  
                            case 4: 
                                itemsOrder.addItems(new ExtraLargeOnionPizza()); 
                                break;    
                        }    
                    } 
                    break; 
                    case 3: { 
                        System.out.println("您选择了香料比萨"); 
                        System.out.println("请输入香料比萨的大小:"); 
                        System.out.println("------------------------------------"); 
                        System.out.println("  1. 小香料比萨 "); 
                        System.out.println("  2. 中香料比萨 ");  
                        System.out.println("  3. 大香料比萨 "); 
                        System.out.println("  4. 超大香料比萨 "); 
                        System.out.println("------------------------------------"); 

                        int masalapizzasize = Integer.parseInt(br.readLine()); 
                        switch (masalapizzasize) { 
                            case 1: 
                                itemsOrder.addItems(new SmallMasalaPizza()); 
                                break; 
                            case 2: 
                                itemsOrder.addItems(new MediumMasalaPizza()); 
                                break;  
                            case 3: 
                                itemsOrder.addItems(new LargeMasalaPizza()); 
                                break;  
                            case 4: 
                                itemsOrder.addItems(new ExtraLargeMasalaPizza()); 
                                break;    
                        }    
                    } 
                    break;   
                }   
            } 
            break; 
            case 2: { 
                System.out.println("您选择了非素食比萨"); 
                System.out.println("\n\n"); 
                System.out.println("请输入非素食比萨的大小:"); 
                System.out.println("------------------------------------"); 
                System.out.println("  1. 小非素食比萨 "); 
                System.out.println("  2. 中非素食比萨 "); 
                System.out.println("  3. 大非素食比萨 "); 
                System.out.println("  4. 超大非素食比萨 "); 
                System.out.println("------------------------------------"); 

                int nonvegpizzasize = Integer.parseInt(br.readLine());  
                switch (nonvegpizzasize) { 
                    case 1: 
                        itemsOrder.addItems(new SmallNonVegPizza()); 
                        break; 
                    case 2: 
                        itemsOrder.addItems(new MediumNonVegPizza()); 
                        break;  
                    case 3: 
                        itemsOrder.addItems(new LargeNonVegPizza()); 
                        break;  
                    case 4: 
                        itemsOrder.addItems(new ExtraLargeNonVegPizza()); 
                        break;    
                }  
            } 
            break; 
            default: 
                break; 
        } 

        // continued...
        System.out.println("请输入冷饮的选择:"); 
        System.out.println("============================"); 
        System.out.println("    1. 百事可乐      "); 
        System.out.println("    2. 可口可乐       "); 
        System.out.println("    3. 退出       "); 
        System.out.println("============================");  

        int coldDrink = Integer.parseInt(br.readLine()); 
        switch (coldDrink) { 
            case 1: { 
                System.out.println("您选择了百事可乐"); 
                System.out.println("请输入百事可乐的大小:"); 
                System.out.println("------------------------"); 
                System.out.println("  1. 小百事可乐 "); 
                System.out.println("  2. 中百事可乐 "); 
                System.out.println("  3. 大百事可乐 "); 
                System.out.println("------------------------"); 

                int pepsisize = Integer.parseInt(br.readLine()); 
                switch (pepsisize) { 
                    case 1: 
                        itemsOrder.addItems(new SmallPepsi()); 
                        break; 
                    case 2: 
                        itemsOrder.addItems(new MediumPepsi()); 
                        break;  
                    case 3: 
                        itemsOrder.addItems(new LargePepsi()); 
                        break;  
                } 
            }  
            break; 
            case 2: { 
                System.out.println("您选择了可口可乐"); 
                System.out.println("请输入可口可乐的大小:"); 
                System.out.println("------------------------"); 
                System.out.println("  1. 小可口可乐 "); 
                System.out.println("  2. 中可口可乐 "); 
                System.out.println("  3. 大可口可乐 "); 
                System.out.println("  4. 超大可口可乐 "); 
                System.out.println("------------------------"); 

                int cokesize = Integer.parseInt(br.readLine()); 
                switch (cokesize) { 
                    case 1: 
                        itemsOrder.addItems(new SmallCoke()); 
                        break; 
                    case 2: 
                        itemsOrder.addItems(new MediumCoke()); 
                        break;  
                    case 3: 
                        itemsOrder.addItems(new LargeCoke()); 
                        break;    
                }    
            } 
            break; 
            default: 
                break;     
        } // Cold-Drink switch 结束
        return itemsOrder; 
    } // preparePizza() 方法结束
}

步骤 15:创建一个 BuilderDemo 类,它将使用 OrderBuilder 类。

文件:BuilderDemo.java

import java.io.IOException; 

public class BuilderDemo { 
    public static void main(String[] args) throws IOException { 
        // TODO 代码应用逻辑在此处
        
        OrderBuilder builder = new OrderBuilder(); 

        OrderedItems orderedItems = builder.preparePizza(); 

        orderedItems.showItems(); 

        System.out.println("\n"); 
        System.out.println("总成本 : " + orderedItems.getCost()); 
    } 
} // BuilderDemo 类结束

输出

5-3.jpg
5-4.jpg

标签: Design Patterns, Design Patterns教程, 设计模式, 软件设计, 结构型模式, 行为型模式, 单例模式, 工厂模式, 观察者模式, 中介者模式, 访问者模式