Java設計模式(四)之建立型模式:建造者模式
一、定義:
建造者模式將一個複雜物件的構建與表示分離,使得同樣的構建過程可以建立不同的表示。
建造者模式的UML結構圖:
建造者模式主要包含四個角色:
Builder:抽象建造者。它宣告為建立一個Product物件的各個部件指定的抽象介面。
ConcreteBuilder:具體建造者,實現Builder抽象介面,構建和裝配各個部件,定義並明確它所建立的表示,並提供一個檢索產品的介面。
Director:指揮者。構建一個使用Builder介面的物件。它主要是用於建立一個複雜的物件,它主要有兩個作用,一是:隔離了客戶與物件的生產過程,二是:負責控制產品物件的生產過程。
Product:產品角色。表示被構造的複雜物件。ConcreteBuilder建立該產品的內部表示並定義它的裝配過程,包含定義組成部件的類,包括將這些部件裝配成最終產品的介面。
二、模式的實現:
KFC裡面一般都有好幾種可供客戶選擇的套餐,它可以根據客戶所點的套餐,然後在後面做這些套餐,返回給客戶的事一個完整的、美好的套餐。下面我們將會模擬這個過程,我們約定套餐主要包含漢堡、薯條、可樂、雞腿等等組成部分,使用不同的組成部分就可以構建出不同的套餐。
首先是套餐類:
public class Meal { private String food; private String drink; public String getFood() { return food; } public void setFood(String food) { this.food = food; } public String getDrink() { return drink; } public void setDrink(String drink) { this.drink = drink; } }
套餐構造器:
public abstract class MealBuilder {
Meal meal = new Meal();
public abstract void buildFood();
public abstract void buildDrink();
public Meal getMeal(){
return meal;
}
}
套餐A、套餐B。這個兩個套餐都是實現抽象套餐類:
public class MealA extends MealBuilder{ public void buildDrink() { meal.setDrink("一杯可樂"); } public void buildFood() { meal.setFood("一盒薯條"); } }
public class MealB extends MealBuilder{
public void buildDrink() {
meal.setDrink("一杯檸檬果汁");
}
public void buildFood() {
meal.setFood("三個雞翅");
}
}
最後是KFC的服務員,它相當於一個指揮者,它決定了套餐是的實現過程,然後給你一個完美的套餐。
public class KFCWaiter {
private MealBuilder mealBuilder;
public void setMealBuilder(MealBuilder mealBuilder) {
this.mealBuilder = mealBuilder;
}
public Meal construct(){
//準備食物
mealBuilder.buildFood();
//準備飲料
mealBuilder.buildDrink();
//準備完畢,返回一個完整的套餐給客戶
return mealBuilder.getMeal();
}
}
測試類:
public class Client {
public static void main(String[] args) {
//服務員
KFCWaiter waiter = new KFCWaiter();
//套餐A
MealA a = new MealA();
//服務員準備套餐A
waiter.setMealBuilder(a);
//獲得套餐
Meal mealA = waiter.construct();
System.out.print("套餐A的組成部分:");
System.out.println(mealA.getFood()+"---"+mealA.getDrink());
}
}
執行結果:
套餐A的組成部分:一盒薯條---一杯可樂
三、模式的優缺點:
1、優點:
(1)將複雜產品的建立步驟分解在不同的方法中,使得建立過程更加清晰,使得我們能夠更加精確的控制複雜物件的產生過程。
(2)將產品的建立過程與產品本身分離開來,可以使用相同的建立過程來得到不同的產品。也就說細節依賴抽象。
(3)每一個具體建造者都相對獨立,而與其他的具體建造者無關,因此可以很方便地替換具體建造者或增加新的具體建造者,使用者使用不同的具體建造者即可得到不同的產品物件。
2、缺點:
(1)建造者模式所建立的產品一般具有較多的共同點,其組成部分相似,如果產品之間的差異性很大,則不適合使用建造者模式,因此其使用範圍受到一定的限制。
(2)如果產品的內部變化複雜,可能會導致需要定義很多具體建造者類來實現這種變化,導致系統變得很龐大。
3、適用場景:
(1)需要生成的產品物件有複雜的內部結構,這些產品物件通常包含多個成員屬性,當建立複雜物件的演算法應該獨立於該物件的組成部分以及它們的裝配方式時。
(2)隔離複雜物件的建立和使用,並使得相同的建立過程可以建立不同的產品。
四、抽象工廠模式和建造者模式的區別:
1、抽象工廠模式實現對產品家族的建立,一個產品家族是這樣的一系列產品:具有不同分類維度的產品組合,採用抽象工廠模式則是不需要關心構建過程,只關心什麼產品由什麼工廠生產即可。而建造者模式則是要求按照指定的藍圖建造產品,它的主要目的是通過組裝零配件而產生一個新產品,兩者的區別還是比較明顯的。
2、我們在抽象工廠模式中使用“工廠”來描述構建者,而在建造者模式中使用“車間”來描述構建者,其實我們已經在說它們兩者的區別了,抽象工廠模式就好比是一個一個的工廠,寶馬車工廠生產寶馬SUV和寶馬VAN,賓士車工廠生產賓士車SUV和賓士VAN,它是從一個更高層次去看物件的構建,具體到工廠內部還有很多的車間,如製造引擎的車間、裝配引擎的車間等,但這些都是隱藏在工廠內部的細節,對外不公佈。也就是對領導者來說,他只要關心一個工廠到底是生產什麼產品的,不用關心具體怎麼生產。
3、而建造者模式就不同了,它是由車間組成,不同的車間完成不同的建立和裝配任務,一個完整的汽車生產過程需要引擎製造車間、引擎裝配車間的配合才能完成,它們配合的基礎就是設計藍圖,而這個藍圖是掌握在車間主任(Director類)手中,它給建造車間什麼藍圖就能生產什麼產品,建造者模式更關心建造過程。雖然從外界看來一個車間還是生產車輛,但是這個車間的轉型是非常快的,只要重新設計一個藍圖,即可產生不同的產品,這有賴於建造者模式的功勞。
4、相對來說,抽象工廠模式比建造者模式的尺度要大,它關注產品整體,而建造者模式關注構建過程,因此建造者模式可以很容易地構建出一個嶄新的產品,只要導演類能夠提供具體的工藝流程。也正因為如此,兩者的應用場景截然不同,如果希望遮蔽物件的建立過程,只提供一個封裝良好的物件,則可以選擇抽象工廠方法模式。而建造者模式可以用在構件的裝配方面,如通過裝配不同的元件或者相同元件的不同順序,可以產生出一個新的物件,它可以產生一個非常靈活的架構,方便地擴充套件和維護系統。
https://blog.csdn.net/chenssy/article/details/11354661#commentBox