Java設計模式之建造者(Builder)模式
建造者模式介紹:
Builder模式是一步一步創建一個複雜對象的創建性模式,它允許用戶在不知道內部構建細節的情況下,可以更精細的控制對象的構造流程。該模式是爲了將構建複雜對象的過程和它的不見解耦,使得構建過程和部件表示隔離起來。因爲一個複雜的對象又很多大量組成部分,如電腦,有主板,顯卡,顯示器,CPU,電源,還有各種小零件等,如何將這些部件裝配成一臺可以使用的電腦,這個配裝過程需要一定的時間,也很複雜,對於這種情況,爲了在構建過程中對外部隱藏實現細節,就可以使用建造者模式將部件和組裝過程分離,使得構建過程和部件都可以自由擴展,兩者之間的耦合也降到最低。
建造者模式的定義:
將一個複雜對象那個的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。建造者模式的使用場景:
3.1相同的方法,不同的執行順序,產生不同的事件結果時3.2多個部件或零件,都可以裝配到一個對象中,但是產生的運行結果又不相同時。
3.3產品類非常複雜,或者產品類中的調用順序不同產生了不同的作用,這個時候使用建造者模式非常適合。
3.4當初始化一個對象特別複雜,如參數多,切很多參數都具有默認值時。- 建造者模式的UML類圖:
角色介紹:
Product產品類——產品的抽象類;
Builder——抽象Builder類,規範產品的組建,一般是由子類實現具體的組建過程;
ConcreteBuilder——具體的Builder類;
Director——統一組裝過程
- 建造者模式的簡單實現:
計算機的組裝過程較爲複雜,並且組裝順序是不固定的,爲了易於理解,我們把計算機組裝的過程簡化爲構建主機,設置操作系統、設置顯示器3各部分,然後通過Director和具體的Builder來構建計算機對象,如下代碼:
Computer.java
/**
計算機抽象類,相當於Product角色
*/
public abstract class Computer {
protected String mBoard;
protected String mDisplay;
protected String mOS;
protected Computer(){
}
//設置主板
public void setmBoard(String mBoard) {
this.mBoard = mBoard;
}
//設置顯示器
public void setmDisplay(String mDisplay) {
this.mDisplay = mDisplay;
}
//設置操作系統
public abstract void setmOS();
@Override
public String toString() {
return "Computer{" +
"mBoard='" + mBoard + '\'' +
", mDisplay='" + mDisplay + '\'' +
", mOS='" + mOS + '\'' +
'}';
}
}
Windows.java
/**
具體的Computer類,Windows
*/
public class Windows extends Computer {
protected Windows(){
}
@Override
public void setmOS() {
mOS = "Windows10";
}
}
Builder.java
/**
* 抽象Builder類
*/
public abstract class Builder {
//設置主機
public abstract void builderBoard(String borad);
//設置顯示器
public abstract void builderDisplay(String display);
//設置操作系統
public abstract void builderOS();
//創建Computer
public abstract Computer create();
}
WindowsBuilder.java
/**
* 具體的Builder類,WindowsBuilder
*/
public class WindowsBuilder extends Builder {
private Computer mComputer = new Windows();
@Override
public void builderBoard(String borad) {
mComputer.setmBoard(borad);
}
@Override
public void builderDisplay(String display) {
mComputer.setmDisplay(display);
}
@Override
public void builderOS() {
mComputer.setmOS();
}
@Override
public Computer create() {
return mComputer;
}
}
Director.java
/**
* Director類,負責構造Computer
*/
public class Director {
Builder mBuilder;
public Director(Builder mBuilder){
this.mBuilder = mBuilder;
}
/**
* 構建對象
* @param board
* @param display
*/
public void construct(String board, String display){
mBuilder.builderBoard(board);
mBuilder.builderDisplay(display);
mBuilder.builderOS();
}
}
Test.java
/**
* 測試代碼
*/
public class Test {
public static void main(String[] args) {
//構造器
Builder builder = new WindowsBuilder();
Director pcDirector = new Director(builder);
//封裝構建過程,
pcDirector.construct("華碩主板","Retina顯示器");
System.out.println("Computer Info : " + builder.create().toString());
}
}
上述實例中,通過具體的WindowsBuilder來構建Windows對象,而Director封裝了構建複雜產品對象的過程,對外隱藏構建細節。Builder與Director一起將一個複雜對象的構建與它的表示分離,使用同樣的構造過程可以創建不同的對象。
值得注意的是,在顯示開發過程中,Director角色經常會被省略。而直接使用一個Builder來進行對象的組裝,這個Builder通常爲鏈式調用,它的關鍵點是每個setter方法都返回自身,也就是return this,這樣就使得setter方法可以鏈式調用,代碼大致如下:
new TestBuilder().setA(“A”).setB(“B”).create();
通過這種形式不僅去除了Director角色,整個結構也更加簡單,也能對Product對象的組裝過程有更精細的控制。