Java設計模式----建造者模式(Builder)
1.什麼是建造者模式
無論是在現實世界中還是在軟體系統中,都存在一些複雜的物件,它們擁有多個組成部分,如汽車,它包括車輪、方向盤、傳送機等各種部件。而對於大多數使用者而言,無須知道這些部件的裝配細節,也幾乎不會使用單獨某個部件,而是使用一輛完整的汽車,可以通過建造者模式對其進行設計與描述,建造者模式可以將部件和其組裝過程分開,一步一步建立一個複雜的物件。使用者只需要指定複雜物件的型別就可以得到該物件,而無須知道其內部的具體構造細節。
在軟體開發中,也存在大量類似汽車一樣的複雜物件,它們擁有一系列成員屬性,這些成員屬性中有些是引用型別的成員物件。而且在這些複雜物件中,還可能存在一些限制條件,如某些屬性沒有賦值則複雜物件不能作為一個完整的產品使用;有些屬性的賦值必須按照某個順序,一個屬性沒有賦值之前,另一個屬性可能無法賦值等。
複雜物件相當於一輛有待建造的汽車,而物件的屬性相當於汽車的部件,建造產品的過程就相當於組合部件的過程。由於組合部件的過程很複雜,因此,這些部件的組合過程往往被“外部化”到一個稱作建造者的物件裡,建造者返還給客戶端的是一個已經建造完畢的完整產品物件,而使用者無須關心該物件所包含的屬性以及它們的組裝方式,這就是建造者模式的模式動機。
2.實現方式
Sunny軟體公司欲開發一個視訊播放軟體,為了給使用者使用提供方便,
該播放軟體提供多種介面顯示模式,如完整模式、精簡模式、記憶模式、網路模式等。
在不同的顯示模式下主介面的組成元素有所差異,如在完整模式下將顯示選單、播放列表、
主視窗、控制條等,在精簡模式下只顯示主視窗和控制條,而在記憶模式下將顯示主視窗、
控制條、收藏列表等。嘗試使用建造者模式設計該軟體。
分析:
介面為產品類,介面顯示模式為建造者類
實現模式:
建造者模式(不要使用橋接模式哦,看似有兩個維度的變化,其實沒有)
package cn.limbo.design_patterns.builder;
/**
* 產品類
* Created by limbo on 2016/12/10.
*/
public class Player {
//實際上這些型別都是有實體類的,為了簡單起見,全都使用了String型別
private String menu; //選單
private String playList; //播放列表
private String mainWindow; //主視窗
private String controller; // 控制條
private String keepList; // 收藏列表
public Player() {
}
public String getMenu() {
return menu;
}
public void setMenu(String menu) {
this.menu = menu;
}
public String getPlayList() {
return playList;
}
public void setPlayList(String playList) {
this.playList = playList;
}
public String getMainWindow() {
return mainWindow;
}
public void setMainWindow(String mainWindow) {
this.mainWindow = mainWindow;
}
public String getController() {
return controller;
}
public void setController(String controller) {
this.controller = controller;
}
public String getKeepList() {
return keepList;
}
public void setKeepList(String keepList) {
this.keepList = keepList;
}
@Override
public String toString() {
return "Player{" +
"menu='" + menu + '\'' +
", playList='" + playList + '\'' +
", mainWindow='" + mainWindow + '\'' +
", controller='" + controller + '\'' +
", keepList='" + keepList + '\'' +
'}';
}
}
PlayerBuilder.javapackage cn.limbo.design_patterns.builder;
/**
* 產品類建造者
* 抽象類
* Created by limbo on 2016/12/10.
*/
public abstract class PlayerBuilder {
//方便子類進行訪問
protected Player player = new Player();
//產品的基礎的構件
public abstract void buildMainWindow();
public abstract void buildController();
//產品的擴充套件構件
//提供一個預設實現
public void buildMenu() {
this.player.setMenu(null);
}
public void buildPlayList() {
this.player.setPlayList(null);
}
public void buildKeepList() {
this.player.setKeepList(null);
}
// //進行細粒度的控制,決定是否存在相應的物件,一般用於擴充套件功能
// //指揮者進行呼叫,決定是否建造。
// //擴充的子類進行覆寫,預設都是沒有擴充套件功能的
// public boolean hasMenu() {
// return false;
// }
//
// public boolean hasPlayList() {
// return false;
// }
//
// public boolean hasKeepList() {
// return false;
// }
//建立並返回一個建造完成的物件
public Player build() {
//每個player都有的東西先建造
this.buildMainWindow();
this.buildController();
// //如果有選單則建立選單
// if(this.hasMenu()){
// this.buildMenu();
// }
//
// if(this.hasPlayList()){
// this.buildPlayList();
// }
//
// if(this.hasKeepList()){
// this.buildKeepList();
// }
//產品的擴充套件功能
this.buildMenu();
this.buildPlayList();
this.buildKeepList();
return this.player;
}
}
package cn.limbo.design_patterns.builder.concrete_builder;
import cn.limbo.design_patterns.builder.PlayerBuilder;
/**
* 完整模式
* Created by limbo on 2016/12/10.
*/
public class FullModeBuilder extends PlayerBuilder {
@Override
public void buildMainWindow() {
this.player.setMainWindow("完整模式主視窗");
}
@Override
public void buildController() {
this.player.setController("完整模式控制條");
}
@Override
public void buildMenu() {
this.player.setMenu("完整模式選單");
}
@Override
public void buildPlayList() {
this.player.setPlayList("完整模式播放列表");
}
@Override
public void buildKeepList() {
this.player.setKeepList("完整模式收藏列表");
}
}
KeepModeBuilder.java
package cn.limbo.design_patterns.builder.concrete_builder;
import cn.limbo.design_patterns.builder.PlayerBuilder;
/**
* 完整模式
* Created by limbo on 2016/12/10.
*/
public class FullModeBuilder extends PlayerBuilder {
@Override
public void buildMainWindow() {
this.player.setMainWindow("完整模式主視窗");
}
@Override
public void buildController() {
this.player.setController("完整模式控制條");
}
@Override
public void buildMenu() {
this.player.setMenu("完整模式選單");
}
@Override
public void buildPlayList() {
this.player.setPlayList("完整模式播放列表");
}
@Override
public void buildKeepList() {
this.player.setKeepList("完整模式收藏列表");
}
}
package cn.limbo.design_patterns.builder.concrete_builder;
import cn.limbo.design_patterns.builder.PlayerBuilder;
/**
* 完整模式
* Created by limbo on 2016/12/10.
*/
public class FullModeBuilder extends PlayerBuilder {
@Override
public void buildMainWindow() {
this.player.setMainWindow("完整模式主視窗");
}
@Override
public void buildController() {
this.player.setController("完整模式控制條");
}
@Override
public void buildMenu() {
this.player.setMenu("完整模式選單");
}
@Override
public void buildPlayList() {
this.player.setPlayList("完整模式播放列表");
}
@Override
public void buildKeepList() {
this.player.setKeepList("完整模式收藏列表");
}
}
測試類:
package cn.limbo.test;
import cn.limbo.design_patterns.builder.Player;
import cn.limbo.design_patterns.builder.PlayerBuilder;
import cn.limbo.design_patterns.builder.concrete_builder.FullModeBuilder;
import cn.limbo.design_patterns.builder.concrete_builder.KeepModeBuilder;
import cn.limbo.design_patterns.builder.concrete_builder.SimplifyModeBuilder;
import org.junit.Test;
/**
* Created by limbo on 2016/12/10.
*/
public class BuilderTest {
@Test
public void show(){
PlayerBuilder playerBuilder = new KeepModeBuilder();
Player player = playerBuilder.build();
System.out.println(player);
}
}
3.優缺點
1.主要優點
(1) 在建造者模式中,客戶端不必知道產品內部組成的細節,將產品本身與產品的建立過程解耦,使得相同的建立過程可以建立不同的產品物件。
(2) 每一個具體建造者都相對獨立,而與其他的具體建造者無關,因此可以很方便地替換具體建造者或增加新的具體建造者,使用者使用不同的具體建造者即可得到不同的產品物件。由於指揮者類針對抽象建造者程式設計,增加新的具體建造者無須修改原有類庫的程式碼,系統擴充套件方便,符合“開閉原則”
(3) 可以更加精細地控制產品的建立過程。將複雜產品的建立步驟分解在不同的方法中,使得建立過程更加清晰,也更方便使用程式來控制建立過程。
2.主要缺點
(1) 建造者模式所建立的產品一般具有較多的共同點,其組成部分相似,如果產品之間的差異性很大,例如很多組成部分都不相同,不適合使用建造者模式,因此其使用範圍受到一定的限制。
(2) 如果產品的內部變化複雜,可能會導致需要定義很多具體建造者類來實現這種變化,導致系統變得很龐大,增加系統的理解難度和執行成本。
4.適用場景
在以下情況下可以考慮使用建造者模式:
(1) 需要生成的產品物件有複雜的內部結構,這些產品物件通常包含多個成員屬性。
(2) 需要生成的產品物件的屬性相互依賴,需要指定其生成順序。
(3) 物件的建立過程獨立於建立該物件的類。在建造者模式中通過引入了指揮者類,將建立過程封裝在指揮者類中,而不在建造者類和客戶類中。
(4) 隔離複雜物件的建立和使用,並使得相同的建立過程可以建立不同的產品。
5.與工廠模式的區別
6.與外觀模式的區別
相關文章
- Java設計模式之建造者模式(Builder)Java設計模式UI
- 設計模式-建造者模式(Builder)設計模式UI
- JAVA設計模式之 建造者模式【Builder Pattern】Java設計模式UI
- 設計模式--建造者模式(Builder Pattern)設計模式UI
- 設計模式之-建造者模式-Builder設計模式UI
- 設計模式--建造者模式Builder(建立型)設計模式UI
- 重識設計模式-建造者模式(Builder Pattern)設計模式UI
- C#設計模式-建造者模式(Builder Pattern)C#設計模式UI
- 人人都會設計模式---建造者模式--Builder設計模式UI
- C#設計模式系列:建造者模式(Builder)C#設計模式UI
- 建造者模式(Builder)模式UI
- 人人都會設計模式: 07、建造者模式--Builder設計模式UI
- 設計模式的征途—6.建造者(Builder)模式設計模式UI
- 設計模式總結篇系列:建造者模式(Builder)設計模式UI
- java設計模式-建造者模式Java設計模式
- 設計模式實戰系列之@Builder和建造者模式設計模式UI
- Java 設計模式(二)《建造者模式》Java設計模式
- JAVA設計模式之建造者模式Java設計模式
- 建造者模式(Builder Pattern)模式UI
- Java設計模式之(三)——建造者模式Java設計模式
- 我的Java設計模式-建造者模式Java設計模式
- 設計模式-建造者模式設計模式
- 設計模式 --建造者模式設計模式
- 設計模式----建造者模式設計模式
- 設計模式 —— 建造者模式設計模式
- 設計模式(建造者模式)設計模式
- 設計模式 | 建造者模式設計模式
- 一天一個設計模式(三) - 建造者模式(Builder)設計模式UI
- 折騰Java設計模式之建造者模式Java設計模式
- Java設計模式之模板方法模式和建造者模式Java設計模式
- 設計模式之建造者模式設計模式
- 設計模式之【建造者模式】設計模式
- 設計模式(六)——建造者模式設計模式
- 設計模式(十六):建造者模式設計模式
- 建造者模式(Builder)(生成器)模式UI
- JAVA設計模式 4【建立型】理解建造者模式Java設計模式
- 重學 Java 設計模式:實戰建造者模式Java設計模式
- java23種設計模式——五、建造者模式Java設計模式