Java設計模式之建造者(Builder)模式

Java設計模式之建造者(Builder)模式

  1. 建造者模式介紹:
    Builder模式是一步一步創建一個複雜對象的創建性模式,它允許用戶在不知道內部構建細節的情況下,可以更精細的控制對象的構造流程。該模式是爲了將構建複雜對象的過程和它的不見解耦,使得構建過程和部件表示隔離起來。

    因爲一個複雜的對象又很多大量組成部分,如電腦,有主板,顯卡,顯示器,CPU,電源,還有各種小零件等,如何將這些部件裝配成一臺可以使用的電腦,這個配裝過程需要一定的時間,也很複雜,對於這種情況,爲了在構建過程中對外部隱藏實現細節,就可以使用建造者模式將部件和組裝過程分離,使得構建過程和部件都可以自由擴展,兩者之間的耦合也降到最低。
     

  2. 建造者模式的定義:
     
    將一個複雜對象那個的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。

  3. 建造者模式的使用場景:
     
     3.1相同的方法,不同的執行順序,產生不同的事件結果時

     3.2多個部件或零件,都可以裝配到一個對象中,但是產生的運行結果又不相同時。
     
     3.3產品類非常複雜,或者產品類中的調用順序不同產生了不同的作用,這個時候使用建造者模式非常適合。
     
     3.4當初始化一個對象特別複雜,如參數多,切很多參數都具有默認值時。

  4. 建造者模式的UML類圖:
     
    角色介紹:
     
    Product產品類——產品的抽象類;
     
    Builder——抽象Builder類,規範產品的組建,一般是由子類實現具體的組建過程;
      
    ConcreteBuilder——具體的Builder類;
     
    Director——統一組裝過程
     
     
  5. 建造者模式的簡單實現:
     
     計算機的組裝過程較爲複雜,並且組裝順序是不固定的,爲了易於理解,我們把計算機組裝的過程簡化爲構建主機,設置操作系統、設置顯示器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對象的組裝過程有更精細的控制。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章