建造者模式是較爲複雜的建立型模式,它將客戶端與包含多個組成部分(或部件)的複雜對象的建立過程分離,客戶端無須知道複雜對象的內部組成部分與裝配方式,只須要知道所需建造者的類型便可。它關注如何一步一步建立一個的複雜對象,不一樣的具體建造者定義了不一樣的建立過程,且具體建造者相互獨立,增長新的建造者很是方便,無須修改已有代碼,系統具備較好的擴展性。java
● Builder(抽象建造者):它爲建立一個產品 Product 對象的各個部件指定抽象接口,在該接口中通常聲明兩類方法,一類方法是 buildPartX(),它們用於建立複雜對象的各個部件;另外一類方法是 getResult(),它們用於返回複雜對象。Builder既能夠是抽象類,也能夠是接口。編程
● ConcreteBuilder(具體建造者):它實現了 Builder 接口,實現各個部件的具體構造和裝配方法,定義並明確它所建立的複雜對象,也能夠提供一個方法返回建立好的複雜產品對象。網絡
● Product(產品角色):它是被構建的複雜對象,包含多個組成部件,具體建造者建立該產品的內部表示並定義它的裝配過程。app
● Director(指揮者):指揮者又稱爲導演類,它負責安排複雜對象的建造次序,指揮者與抽象建造者之間存在關聯關係,能夠在其 construct() 建造方法中調用建造者對象的部件構造與裝配方法,完成複雜對象的建造。客戶端通常只須要與指揮者進行交互,在客戶端肯定具體建造者的類型,並實例化具體建造者對象(也能夠經過配置文件和反射機制),而後經過指揮者類的構造函數或者 Setter 方法將該對象傳入指揮者類中。ide
Sunny 軟件公司欲開發一個視頻播放軟件,爲了給用戶使用提供方便,該播放軟件提供多種界面顯示模式,如完整模式、精簡模式、記憶模式、網絡模式等。在不一樣的顯示模式下主界面的組成元素有所差別,如在完整模式下將顯示菜單、播放列表、主窗口、控制條等,在精簡模式下只顯示主窗口和控制條,而在記憶模式下將顯示主窗口、控制條、收藏列表等。嘗試使用建造者模式設計該軟件。函數
一、播放軟件外觀類-Appearanceui
/** * Author: YiFan * Date: 2018/12/13 16:08 * Description: 複雜產品類-視頻播放軟件外觀 */ public class Appearance { // 菜單 private String menu; // 播放列表 private String playLists; // 主窗口 private String mainWindows; // 控制條 private String controlBar; public String getMenu() { return menu; } public void setMenu(String menu) { this.menu = menu; } public String getPlayLists() { return playLists; } public void setPlayLists(String playLists) { this.playLists = playLists; } public String getMainWindows() { return mainWindows; } public void setMainWindows(String mainWindows) { this.mainWindows = mainWindows; } public String getControlBar() { return controlBar; } public void setControlBar(String controlBar) { this.controlBar = controlBar; } @Override public String toString() { return "Appearance{" + "menu='" + menu + '\'' + ", playLists='" + playLists + '\'' + ", mainWindows='" + mainWindows + '\'' + ", controlBar='" + controlBar + '\'' + '}'; } }
二、定義一個接口 IBuildAppearance,構建播放器軟件外觀this
/** * Author: YiFan * Date: 2018/12/13 16:15 * Description: 構建視頻播放軟件外觀 */ public interface IBuildAppearance { void buildMenu(); void buildPlayLists(); void buildMainWindows(); void buildControlBar(); Appearance createAppearance(); }
三、定義三個播放器外觀,實現 IBuildAppearance 接口設計
/** * Author: YiFan * Date: 2018/12/13 16:18 * Description: 完整模式外觀 */ public class FullMode implements IBuildAppearance { private Appearance appearance; public FullMode() { appearance = new Appearance(); } @Override public void buildMenu() { appearance.setMenu("顯示菜單"); } @Override public void buildPlayLists() { appearance.setPlayLists("顯示播放列表"); } @Override public void buildMainWindows() { appearance.setMainWindows("顯示主窗口"); } @Override public void buildControlBar() { appearance.setControlBar("顯示控制條"); } @Override public Appearance createAppearance() { return appearance; } } /** * Author: YiFan * Date: 2018/12/13 16:18 * Description: 精簡模式外觀 */ public class ReducedMode implements IBuildAppearance { private Appearance appearance; public ReducedMode() { appearance = new Appearance(); } @Override public void buildMenu() { appearance.setMenu("不顯示菜單"); } @Override public void buildPlayLists() { appearance.setPlayLists("不顯示播放列表"); } @Override public void buildMainWindows() { appearance.setMainWindows("顯示主窗口"); } @Override public void buildControlBar() { appearance.setControlBar("顯示控制條"); } @Override public Appearance createAppearance() { return appearance; } } /** * Author: YiFan * Date: 2018/12/13 16:19 * Description: 記憶模式外觀 */ public class MemoryMode implements IBuildAppearance { private Appearance appearance; public MemoryMode() { appearance = new Appearance(); } @Override public void buildMenu() { appearance.setMenu("不顯示菜單"); } @Override public void buildPlayLists() { appearance.setPlayLists("顯示播放列表"); } @Override public void buildMainWindows() { appearance.setMainWindows("顯示主窗口"); } @Override public void buildControlBar() { appearance.setControlBar("顯示控制條"); } @Override public Appearance createAppearance() { return appearance; } }
四、定義構造者類code
/** * Author: YiFan * Date: 2018/12/13 16:23 * Description: 建造者-指揮者 */ public class Director { public Appearance construct(IBuildAppearance mode) { mode.buildMenu(); mode.buildPlayLists(); mode.buildMainWindows(); mode.buildControlBar(); return mode.createAppearance(); } }
五、客戶端代碼
/** * Author: YiFan * Date: 2018/12/13 16:26 * Description: */ public class Client { public static void main(String[] args) { // 建立Director對象 Director director = new Director(); // 建立Appearance三個引用變量 Appearance appearance1, appearance2, appearance3; // 建造者經過完整模式構建外觀 appearance1 = director.construct(new FullMode()); // 建造者經過精簡模式構建外觀 appearance2 = director.construct(new ReducedMode()); // 建造者經過記憶模式構建外觀 appearance3 = director.construct(new MemoryMode()); System.out.println(appearance1); System.out.println(appearance2); System.out.println(appearance3); } }
直接結果:
Appearance{menu='顯示菜單', playLists='顯示播放列表', mainWindows='顯示主窗口', controlBar='顯示控制條'} Appearance{menu='不顯示菜單', playLists='不顯示播放列表', mainWindows='顯示主窗口', controlBar='顯示控制條'} Appearance{menu='不顯示菜單', playLists='顯示播放列表', mainWindows='顯示主窗口', controlBar='顯示控制條'}
建造者模式的核心在於如何一步步構建一個包含多個組成部件的完整對象,使用相同的構建過程構建不一樣的產品,在軟件開發中,若是咱們須要建立複雜對象並但願系統具有很好的靈活性和可擴展性能夠考慮使用建造者模式。
(1) 在建造者模式中,客戶端沒必要知道產品內部組成的細節,將產品自己與產品的建立過程解耦,使得相同的建立過程能夠建立不一樣的產品對象。
(2) 每個具體建造者都相對獨立,而與其餘的具體建造者無關,所以能夠很方便地替換具體建造者或增長新的具體建造者,用戶使用不一樣的具體建造者便可獲得不一樣的產品對象。因爲指揮者類針對抽象建造者編程,增長新的具體建造者無須修改原有類庫的代碼,系統擴展方便,符合「開閉原則」
(3) 能夠更加精細地控制產品的建立過程。將複雜產品的建立步驟分解在不一樣的方法中,使得建立過程更加清晰,也更方便使用程序來控制建立過程。
(1) 建造者模式所建立的產品通常具備較多的共同點,其組成部分類似,若是產品之間的差別性很大,例如不少組成部分都不相同,不適合使用建造者模式,所以其使用範圍受到必定的限制。
(2) 若是產品的內部變化複雜,可能會致使須要定義不少具體建造者類來實現這種變化,致使系統變得很龐大,增長系統的理解難度和運行成本。
(1) 須要生成的產品對象有複雜的內部結構,這些產品對象一般包含多個成員屬性。
(2) 須要生成的產品對象的屬性相互依賴,須要指定其生成順序。
(3) 對象的建立過程獨立於建立該對象的類。在建造者模式中經過引入了指揮者類,將建立過程封裝在指揮者類中,而不在建造者類和客戶類中。
(4) 隔離複雜對象的建立和使用,並使得相同的建立過程能夠建立不一樣的產品。