天天看點

設計模式-建造者模式标準模式鍊式簡版

概念

将一個複雜的對象的建構與它的表示分離,使得同樣的建構過程可以有不同的表示。

大概的意思是說:一套的建構過程可以有不同的産品(表示)出來。這些産品(表示)都按照這一套的建構過程被生産出來。

初探

建造者模式屬于建立型模式。比如說:樓房是千差萬别的,樓房的外形,層數,内部房間的數量,房間的裝飾都不一樣。但是對于建造者來說,抽象出來的建築流程是确定的。因為建築一座樓房,都可以歸納為幾個步驟:1打樁、2建地基、3搭架構、4内部建設。同理,建造者設計模式也是基于這樣的概念而生的,這個設計模式用來解決什麼樣的情況呢:即流程不變,但每個流程實作的具體細節是會變化的。這樣的情況,可以考慮使用建造者。就像蓋房子,4個流程都必須有,但每個流程各自的實作細節,各個房子各有不同。 建造者模式的好處就是保證了流程不會變化,即流程不會增加也不會遺漏,也不會産生流程次序的錯誤。而建造者模式,保證了流程的确定性,而流程内部的實作細節,是可繼承擴充的。從根源上解決了流程不規範的問題。

寫代碼的時候,如果你遇到一個需要把控流程,但流程中的實作細節各有許多的方式,你可以采用建造者模式。用一個director類把控流程,而用許多不同的builder去建造流程中的細節并産生産品。這樣,生産出來的産品基本是不會出問題的。因為流程把控好了。你可以有多個builder去負責建造生産産品,而讓director去把控流程。如果有新的産品,但是流程一緻,你可以再擴張出一個builder來。這樣,你看,建造者模式是不是很符合OCP原則呢。

建造者模式注重于房子的零部件的組裝的順序,而工廠模式則注重于建立怎樣的房子.

建造者模式要求建造的過程必須是穩定的,而裝飾模式沒有這個要求

模式中的角色分類

  • Builder:給出一個抽象接口,規範建造者對于生産的産品的各個組成部分的建造。這個接口隻是定一個規範,不涉及具體的建造,具體的建造讓繼承于它的子類(ConcreteBuilder)去實作
  • ConcreteBuilder:實作builder接口,針對不同的商業邏輯,具體化各對象部分的建造,最後傳回一個建造好的産品。實作抽象類的所有未實作的方法,具體來說一般是兩項任務:組建産品;傳回組建好的産品。
  • Director:導演(負責人),顧名思義,負責規範流程之用。在指導中不涉及産品的建立,隻負責保證複雜對象各部分被建立或按某種順序建立。導演類一般不與産品類發生依賴關系,與導演類直接互動的是建造者類。一般來說,導演類被用來封裝程式中易變的部分。
  • Product:複雜對象。

角色UML關系圖如下

設計模式-建造者模式标準模式鍊式簡版

以建立AlertDialog為例子

目前,建立者模式,有很多變種.

标準模式

UML圖如下

設計模式-建造者模式标準模式鍊式簡版

java代碼

抽象接口

package demo10;

/**
 * 
 * @ClassName: DialogBuilder
 * @Description:抽象接口
 * @author cheng
 * @date 2017-8-15 下午02:02:06
 */
public interface DialogBuilder {
    /**
     * 
     * @Title: createBackGround
     * @Description: 建立背景
     * @param s
     * @return
     */
    DialogBuilder createBackGround(String s);

    /**
     * 
     * @Title: createShape
     * @Description: 建立形狀
     * @param s
     * @return
     */
    DialogBuilder createShape(String s);

    /**
     * 
     * @Title: createTitle
     * @Description: 建立标題
     * @param s
     * @return
     */
    DialogBuilder createTitle(String s);

    /**
     * 
     * @Title: build
     * @Description: 建立對象并傳回
     * @return
     */
    Object build();
}
           

具體實作類

package demo10;

/**
 * 
 * @ClassName: AlertDialogBuilder
 * @Description:具體建構類
 * @author cheng
 * @date 2017-8-15 下午02:13:39
 */
public class AlertDialogBuilder implements DialogBuilder {

    //持有産品的引用
    private AlertDialog alertDialog;

    public AlertDialogBuilder() {
        alertDialog = new AlertDialog();
    }

    @Override
    public DialogBuilder createBackGround(String s) {
        alertDialog.setBackGround(s);
        return this;
    }

    @Override
    public DialogBuilder createShape(String s) {
        alertDialog.setShape(s);
        return this;
    }

    @Override
    public DialogBuilder createTitle(String s) {
        alertDialog.setTitle(s);
        return this;
    }

    @Override
    public AlertDialog build() {
        return alertDialog;
    }

}
           

産品類

package demo10;

/**
 * 
 * @ClassName: AlertDialog
 * @Description:産品類
 * @author cheng
 * @date 2017-8-15 下午02:08:35
 */
public class AlertDialog {

    private String backGround;
    private String shape;
    private String title;

    /**
     * 複寫
     */
    @Override
    public String toString() {
        return "AlertDialog[backGround=" + backGround + ",shape=" + shape
                + ",title=" + title + "]";
    }

    public AlertDialog() {
    }

    public AlertDialog(String backGround, String shape, String title) {
        super();
        this.backGround = backGround;
        this.shape = shape;
        this.title = title;
    }

    public String getBackGround() {
        return backGround;
    }

    public void setBackGround(String backGround) {
        this.backGround = backGround;
    }

    public String getShape() {
        return shape;
    }

    public void setShape(String shape) {
        this.shape = shape;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

}
           

導演類

package demo10;

/**
 * 
 * @ClassName: DialogDirector
 * @Description:導演類
 * @author cheng
 * @date 2017-8-15 下午02:19:11
 */
public class DialogDirector {

    // 持有抽象接口的引用
    private DialogBuilder dialogBuilder;

    public DialogDirector() {
        dialogBuilder = new AlertDialogBuilder();
    }

    public AlertDialog createDialog(String background, String shape,
            String title) {
        return (AlertDialog) dialogBuilder.createBackGround(background)
                .createShape(shape).createTitle(title).build();
    }
}
           

測試

package demo10;

/**
 * 
 * @ClassName: ClientTest
 * @Description:測試
 * @author cheng
 * @date 2017-8-15 下午02:21:52
 */
public class ClientTest {

    public static void main(String[] args) {
        AlertDialog alertDialog1 = new DialogDirector().createDialog("黑色",
                "長方形", "是否删除");
        System.out.println(alertDialog1);
    }
}
           

運作結果

設計模式-建造者模式标準模式鍊式簡版

鍊式簡版

隻包括建造者類,産品參數内部類,産品類

UML圖如下

設計模式-建造者模式标準模式鍊式簡版

java代碼

具體建造類

package demo11;

/**
 * 
 * @ClassName: AlertDialogBuilder
 * @Description:具體建構類
 * @author cheng
 * @date 2017-8-15 下午02:13:39
 */
public class AlertDialogBuilder {

    private AlertDialogParams alertDialogParams;

    /**
     * 初始化建造者,初始化AlertDialogparams中間件
     */
    public AlertDialogBuilder() {
        alertDialogParams = new AlertDialogParams();
    }

    /**
     * 
     * @ClassName: AlertDialogparams
     * @Description:内部類來作為中間量,作為建造對象的參數傳入,屬性和産品類相同
     * @author cheng
     * @date 2017-8-15 下午03:58:21
     */
    class AlertDialogParams {
        String backGround;
        String shape;
        String title;
    }

    /**
     * 
     * @Title: createBackGround
     * @Description: 傳回自身AlertDialogBuilder,鍊式調用
     * @param s
     * @return
     */
    public AlertDialogBuilder createBackGround(String s) {
        alertDialogParams.backGround = s;
        return this;
    }

    public AlertDialogBuilder createShape(String s) {
        alertDialogParams.shape = s;
        return this;
    }

    public AlertDialogBuilder createTitle(String s) {
        alertDialogParams.title = s;
        return this;
    }

    /**
     * 建立AlertDialog對象,将中間量alertDialogParams傳入AlertDialog,進行建構.
     */
    public AlertDialog build() {
        AlertDialog alertDialog = new AlertDialog();
        alertDialog.init(alertDialogParams);
        return alertDialog;
    }

}
           

産品類

package demo11;

/**
 * 
 * @ClassName: AlertDialog
 * @Description:産品類
 * @author cheng
 * @date 2017-8-15 下午03:50:09
 */
public class AlertDialog {
    private String backGround;
    private String shape;
    private String title;

    /**
     * 
     * @Title: init
     * @Description: 初始化
     * @param params
     */
    public void init(AlertDialogBuilder.AlertDialogParams params) {
        this.backGround = params.backGround;
        this.shape = params.shape;
        this.title = params.title;
    }

    /**
     * 複寫
     */
    @Override
    public String toString() {
        return "AlertDialog[backGround=" + backGround + ",shape=" + shape
                + ",title=" + title + "]";
    }

    public AlertDialog() {
    }

    public String getBackGround() {
        return backGround;
    }

    public void setBackGround(String backGround) {
        this.backGround = backGround;
    }

    public String getShape() {
        return shape;
    }

    public void setShape(String shape) {
        this.shape = shape;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

}
           

測試

package demo11;

/**
 * 
 * @ClassName: ClientTest
 * @Description:測試
 * @author cheng
 * @date 2017-8-15 下午02:21:52
 */
public class ClientTest {

    public static void main(String[] args) {
        AlertDialog alertDialog = new AlertDialogBuilder()
                                        .createBackGround("黑色")
                                        .createShape("圓形")
                                        .createTitle("确認登入")
                                        .build();
        System.out.println(alertDialog);
    }
}
           

運作結果

設計模式-建造者模式标準模式鍊式簡版

好處

使用建造者模式可以使用戶端不必知道産品内部組成的細節。

具體的建造者類之間是互相獨立的,對系統的擴充非常有利。

由于具體的建造者是獨立的,是以可以對建造過程逐漸細化,而不對其他的子產品産生任何影響。

使用場合

建立一些複雜的對象時,這些對象的内部組成構件間的建造順序是穩定的,但是對象的内部組成構件面臨着複雜的變化

要建立的複雜對象的算法,獨立于該對象的組成部分,也獨立于組成部分的裝配方法時。

繼續閱讀