学习笔记:模式学习-生成器模式
前言
在前兩講,我們介紹了工廠方法和抽象工廠模式,這兩種模式都是完成對一個或者若干個內部結構相對簡單的對象的創建工作。換句話來說,這樣的對象內部之間沒有明顯的子部分或者說是各個子部分間的“組裝”過程。然而在現實世界里,確實存在著這樣的對象模型,可以將內部抽象成若干個子部分,而且需要通過一定的組建算法將它們構建在一起形成完整的最終對象。面對類似對象的創建工作,顯然工廠模式已經不善長,需要追尋新的模式來更好地應對上述需求。
動機
在實際軟件系統中,經常面臨著“一個復雜對象”的創建問題,而其通常是由多個子部分通過一定的構建算法組裝形成。由于用戶需求的變化,這個“復雜對象”的各個子部分也經常面臨著劇烈的變化,但是子部分之間組裝算法卻比較穩定。如何提供一種“封裝機制”來隔離出“復雜對象中各個子部分”的變化,從而保持系統對這個復雜對象的“穩定構建算法”不會隨著需求的改變而改變?面對這樣的需求,生成器模式可以較好地處理。
意圖
將一個復雜對象的構建和它的表示分離,便得同樣的構建過程可以創建不同的表示。
結構圖
代碼示例
1: public abstract class Builder{ 2: public abstract void buildPartA(); 3: public abstract void buildPartB(); 4: public abstract Product getProduct(); 5: } 6: ? 7: public class ConcreteBuilder1 extends Builder{ 8: private Product product; 9: public void buildPartA(){ 10: product.addPart("PartA"); 11: } 12: public void buildPartB(){ 13: product.addPart("PartB"); 14: } 15: ? 16: public Product getProduct(){ 17: if(product!=null) 18: return product; 19: else 20: return null; 21: } 22: } 23: ? 24: public class ConcreteBuilder2 extends Builder{ 25: private Product product; 26: public void buildPartA(){ 27: product.addPart("PartX"); 28: } 29: public void buildPartB(){ 30: product.addPart("PartY"); 31: } 32: ? 33: public Product getProduct(){ 34: if(product!=null) 35: return product; 36: else 37: return null; 38: } 39: } 40: ? 41: public class Director{ 42: public void construct(Builder builder){ 43: builder.buildPartA(); 44: builder.buildPartB(); 45: } 46: } 47: ? 48: public class Product{ 49: private ArrayList<String> product; 50: public void addPart(String partName){ 51: product.add(partName); 52: } 53: ? 54: public void showProduct(){ 55: for (String part : product) { 56: System.out.println(part); 57: } 58: } 59: ? 60: } 61: ? 62: public class Client{ 63: public static void main(String[] args){ 64: Director director=new Director(); 65: ? 66: Builder concreteBuilder1=new ConcreteBuilder1(); 67: director.construct(concreteBuilder1); 68: Product product1=concreteBuilder1.getProduct(); 69: product1.showProduct(); 70: ? 71: Builder concreteBuilder2=new ConcreteBuilder2(); 72: director.construct(concreteBuilder2); 73: Product product2=concreteBuilder2.getProduct(); 74: product2.showProduct(); 75: } 76: } 從上述示例代碼中,我們可以清楚地看到,生成器模式是如何將一個“復雜對象”分步地構建并組裝其各個子部分的,雖然在這里我們只是通過字符串來簡單地表示各個子部分對象,但是這并不妨礙詮釋對生成器模式的demo演示。在實際的軟件系統中,各個子部分對象完全有可能通過相應的工廠方法來生成,然后再交由生成器按照特定的構建算法將其組裝成一個完整的“復雜對象”。所以,在這里我們不必拘泥于細節的實現,只要理解生成器模式本質和實現方式即可,再通過聯想實際生活中的種種模式,相信具有OO思想的你,不難將其抽象成生成器模式所適宜的應用場景。現實場景
其實,在現實場景中,有很多適用于生成器模式來解決的應用。比如Terrylee所描述的KFC場景,這種模式用于快餐店制作兒童餐。典型的兒童餐包括一個主食,一個輔食,一杯飲料和一個玩具(例如漢堡、炸雞、可樂和玩具車)。這些在不同的兒童餐中可以是不同的,但是組合成兒童餐的過程是相同的(這是關鍵點)。無論顧客點的是漢堡,三名治還是雞肉,過程都是一樣的。柜臺的員工直接把主食,輔食和玩具放在一起。這些是放在一個袋子中的。飲料被倒入杯中,放在袋子外邊。這些過程在相互競爭的餐館中是同樣的。在這樣一種場景中,主食、輔食、飲料和玩具根據所選擇的套餐種類的不同而不同,但是不管何種套餐,都具有這幾大部分,也就是說組裝的過程是一致的,不同的只是子部分的實現不同而已,但是這并不妨礙子部分的組裝流程。這不完全符合生成器模式的適用場景嗎?
這樣的例子有很多,比如我們日常工作學習所離不開的電腦,其制造過程何嘗不是一種抽象意義上的生成器模式呢?雖然不同品牌的電腦內部的各個組成部件會有所不同,根據自身的定位和需求使用不同廠家生產的部件,但是不管是蘋果電腦還是索尼電腦,它們之間的組成元素都是相同的,都有處理器、主板、顯卡、顯示器等核心組成部件。所謂的電腦生產過程,簡單來說就是按照一定順序將上述所有部件組裝起來,而這個組裝算法相對來說是穩定不變的,變得只是電腦各個子部分不同而已,與KFC例子類似,完完全全與生成器模式的應用相符合。大家可以充分發揮想像力,聯想到現實世界的種種應用場景與生成器模式結合起來。
實現要點
運用效果
適用性
相關模式
總結
生成器模式的本質:分離整體構建算法和部件構造表示。構建一個復雜對象,需要將整體的構建過程與復雜對象子部件的構建過程分離開來,這樣才能使得程序結構更松散、易擴展,復用性好,同樣也會使代碼邏輯更清晰,意圖更明顯。生成器模式的重心還是在于分離整體構建算法與子部件的構建,分步驟構建對象只不過是整體構建算法的一個簡單表現,或者說是一個附帶產物。說了這么多,也摘抄了其他優秀博文和書籍的經典論述,希望大家對生成器模式會有一個全面、深刻的理解和掌握。下一篇將介紹原型模式,敬請期待。
總結
以上是生活随笔為你收集整理的学习笔记:模式学习-生成器模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: COMSOL6.0 版本新功能:求解大型
- 下一篇: 如何将音频从视频分离到单独的音轨?