構建者模式(Builder Pattern)是一種創建型設計模式。該模式通過一步步構建的方式創建複雜對象。在本篇文章中,我們將從以下幾個方面對構建者模式進行詳細的闡述:
一、基本定義
構建者模式的主要思想是將一個複雜對象的構建過程與它的表示分離,從而同樣的構建過程可以變換不同的表示。該模式將對象的構建過程簡單化,用戶無需知道類的內部結構,即可獲取到複雜的對象。
public interface Item {
public String name();
public Packing packing();
public float price();
}
二、角色說明
下面介紹構建者模式中的幾個角色:
- Product(產品):被構建的複雜對象。
- Builder(構建者):抽象的介面或者抽象類,定義了複雜對象的構建過程。
- ConcreteBuilder(具體的構建者):實現Builder介面,負責具體的構建過程。
- Director(指揮者):負責調用Builder介面並構造複雜對象,包含一個Builder引用。
三、使用場景
構建者模式通常應用於以下幾種情況:
- 需要生產的產品具有複雜的內部結構。
- 需要生產的產品的構建過程有多種可能性。
- 需要在不同的情況下構建不同的表示。
- 需要隱藏複雜對象的創建過程,使得客戶端可以直接操作最終的產品。
四、優缺點
構建者模式的優點包括:
- 將對象的構建過程與表示分離,使得同樣的構建過程可以得到不同的表示。
- 隱藏了複雜對象的創建過程,使得客戶端可以直接操作最終的產品。
構建者模式的缺點包括:
- 需要定義多個Builder類,增加了系統的複雜度。
- 建造者模式的創建對象是有順序的,所以一旦順序出錯的話,程序將出錯。
五、代碼實現
下面展示一個例子,我們創建一個漢堡店,提供各種不同口味的漢堡,顧客可以自己選擇口感和配料,店鋪會根據顧客的口味構建漢堡,並將最終的漢堡呈現給顧客。
1. Item介面
我們定義一個Item介面,表示可能購買的食品。
public interface Item {
public String name();
public Packing packing();
public float price();
}
2. Packing介面
我們再定義一個Packing介面,表示購物袋等包裝材料。
public interface Packing {
public String pack();
}
3. 容器實現類
我們通過創建實現Packing介面的類 來包裝Item介面。
public class Wrapper implements Packing {
@Override
public String pack() {
return "Wrapper";
}
}
public class Bottle implements Packing {
@Override
public String pack() {
return "Bottle";
}
}
4. 漢堡實現類
我們創建一個實現Item介面的抽象類,以便於提供默認的功能
public abstract class Burger implements Item {
@Override
public Packing packing() {
return new Wrapper();
}
@Override
public abstract float price();
}
public abstract class ColdDrink implements Item {
@Override
public Packing packing() {
return new Bottle();
}
@Override
public abstract float price();
}
5. 食品實現類
我們創建擴展Burger和ColdDrink的實體類。
public class VegBurger extends Burger {
@Override
public float price() {
return 25.0f;
}
@Override
public String name() {
return "Veg Burger";
}
}
public class ChickenBurger extends Burger {
@Override
public float price() {
return 50.5f;
}
@Override
public String name() {
return "Chicken Burger";
}
}
public class Coke extends ColdDrink {
@Override
public float price() {
return 30.0f;
}
@Override
public String name() {
return "Coke";
}
}
public class Pepsi extends ColdDrink {
@Override
public float price() {
return 35.0f;
}
@Override
public String name() {
return "Pepsi";
}
}
6. Meal類
我們創建一個Meal類,其中包含各種Item,並提供一個計算金額的方法。
import java.util.ArrayList;
import java.util.List;
public class Meal {
private List items = new ArrayList();
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());
}
}
}
7. MealBuilder類
我們創建一個MealBuilder類,用於創建不同類型的Meal對象。
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;
}
}
8. Demo類
我們創建一個Demo類,展示使用MealBuilder的過程。
public class Demo {
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());
}
}
六、總結
構建者模式的優點是將對象的構建過程與表示分離,使得同樣的構建過程可以得到不同的表示;隱藏了複雜對象的創建過程,用戶無需知道類的內部結構,即可獲取到複雜的對象。而缺點在於需要定義多個Builder類,建造者模式的創建對象是有順序的,所以一旦順序出錯的話,程序將出錯。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/240728.html