流水作業大家應該都清楚吧!在流水作業中,我們可以將一些複雜的東西給構建出來,例如汽車。我們都知道汽車內部構件比較複雜,由很多部件組成,例如車輪、車門、發動機、方向盤等等,對於我們用戶來說我們並不需要知道這個汽車是如何構建出來的,它的各個部件是如何組裝,我們只需要知道一點:這是一輛完整的汽車。同樣KFC也是這樣的,在KFC中我們吃套餐也不需要知道這個套餐是怎樣做出來的,我們只需要在店裏面向服務員點就可以得到相應的套餐了。對於這兩個例子我們通過指定某個對象類型就可以得到一個完整的對象,而無須關心其內部的構建。
在軟件開發中,也會存在一些構造非常複雜的對象,這些對象擁有一系列的成員屬性,這些成員屬性有些是基本數據類型,有些是引用類型,總之就是一句話,這個對象的構建比較複雜。在這裏我們就將複雜對象當做汽車,成員屬性當做部件,對象的構建當做汽車的組合。對於用戶而言我們總是希望我們在使用對象時足夠簡單,如果一個複雜的對象直接丟給用戶,用戶會是痛苦不堪的(給你一堆部件,你來組裝成一輛汽車看看),除了這個構建的過程外,可能用戶會忘記某些成員屬性。所以我們就希望能夠像使用汽車一樣使用複雜的對象:直接告訴你我需要的對象名或者對象類型,你返回一個完成的對象實例給我。建造者返回給客戶一個完整的的產品對象,而客戶端無須關心該對象所包含的額屬性和組建方式,這就是建造者模式的設計動機。
一、模式定義
建造者模式將一個複雜對象的構建與表示分離,使得同樣的構建過程可以創建不同的表示。
建造者模式構建複雜對象就像造汽車一樣,是一個一個組件一個一個步驟創建出來的,它允許用戶通過制定的對象類型和內容來創建他們,但是用戶並不需要知道這個複雜對象是如何構建的,它只需要明白通過這樣做我可以得到一個完整的複雜對象實例。
二、模式結構
建造者模式的UML結構圖:
建造者模式主要包含四個角色:
Builder:抽象建造者。它聲明爲創建一個Product對象的各個部件指定的抽象接口。
ConcreteBuilder:具體建造者。實現抽象接口,構建和裝配各個部件。
Director:指揮者。構建一個使用Builder接口的對象。它主要是用於創建一個複雜的對象,它主要有兩個作用,一是:隔離了客戶與對象的生產過程,二是:負責控制產品對象的生產過程。
Product:產品角色。一個具體的產品對象。
三、模式實現
KFC裏面一般都有好幾種可供客戶選擇的套餐,它可以根據客戶所點的套餐,然後在後面做這些套餐,返回給客戶的事一個完整的、美好的套餐。下面我們將會模擬這個過程,我們約定套餐主要包含漢堡、薯條、可樂、雞腿等等組成部分,使用不同的組成部分就可以構建出不同的套餐。
首先是套餐類:Meal.java
然後是套餐構造器:MealBuilder.java
然後是套餐A、套餐B。這個兩個套餐都是實現抽象套餐類。
最後是KFC的服務員,它相當於一個指揮者,它決定了套餐是的實現過程,然後給你一個完美的套餐。
測試類
運行結果:
套餐A的組成部分:一盒薯條---一杯可樂
四、模式優缺點
優點
1、將複雜產品的創建步驟分解在不同的方法中,使得創建過程更加清晰,使得我們能夠更加精確的控制複雜對象的產生過程。
2、將產品的創建過程與產品本身分離開來,可以使用相同的創建過程來得到不同的產品。也就說細節依賴抽象。
3、每一個具體建造者都相對獨立,而與其他的具體建造者無關,因此可以很方便地替換具體建造者或增加新的具體建造者,用戶使用不同的具體建造者即可得到不同的產品對象。
缺點
1、建造者模式所創建的產品一般具有較多的共同點,其組成部分相似,如果產品之間的差異性很大,則不適合使用建造者模式,因此其使用範圍受到一定的限制。
2、如果產品的內部變化複雜,可能會導致需要定義很多具體建造者類來實現這種變化,導致系統變得很龐大。
五、模式適用場景
1、需要生成的產品對象有複雜的內部結構,這些產品對象通常包含多個成員屬性。
2、隔離複雜對象的創建和使用,並使得相同的創建過程可以創建不同的產品。
六。模式總結
1、建造者模式是將一個複雜對象的創建過程給封裝起來,客戶只需要知道可以利用對象名或者類型就能夠得到一個完整的對象實例,而不需要關心對象的具體創建過程。
2、建造者模式將對象的創建過程與對象本身隔離開了,使得細節依賴於抽象,符合依賴倒置原則。可以使用相同的創建過程來創建不同的產品對象。