天天看點

建立型設計模式 -- 建造者模式

   建立型設計模式 -- 建造者模式

一、小案例分析

1、功能需求:

  現需要建房子,建房流程:挖地基、砌牆、封頂。對于不同種類的房子(高樓,别墅),流程雖然一樣,但是具體功能實作不同。如何實作建房子?

2、小菜雞的答案:

(1)定義一個抽象接口,并定義三個抽象方法(挖地基、砌牆、封頂)。

(2)對于不同種類的房子,實作該接口,并重寫相關方法即可。

(3)代碼實作:

package builder.pattern;/**
 * 測試類
 * */public class BuilderDemo {    public static void main(String[] args) {
        System.out.println("建别墅流程:");
        BuilderHouse villa = new Villa();

        System.out.println("\n建高樓流程");
        BuilderHouse highBuild = new HighBuild();
    }
}/**
 * 定義一個建房子的接口,并定義其流程 */interface BuilderHouse {    void scoopHole(); // 挖地基

    void buildWall(); // 砌牆

    void topOff(); // 封頂}/**
 * 建别墅,實作建房子的接口
 * */class Villa implements BuilderHouse {    /**
     * 建别墅流程     */
    public Villa() {
        scoopHole();
        buildWall();
        topOff();
    }

    @Override    public void scoopHole() {
        System.out.println("挖10米地基");
    }

    @Override    public void buildWall() {
        System.out.println("砌10層牆");
    }

    @Override    public void topOff() {
        System.out.println("樓頂建個遊泳池");
    }
}/**
 * 建高樓流程,實作建房子的接口
 * */class HighBuild implements BuilderHouse {    /**
     * 建高樓流程     */
    public HighBuild() {
        scoopHole();
        buildWall();
        topOff();
    }

    @Override    public void scoopHole() {
        System.out.println("挖30米地基");
    }

    @Override    public void buildWall() {
        System.out.println("砌60層牆");
    }

    @Override    public void topOff() {
        System.out.println("樓頂建個停機坪");
    }
}      

(4)代碼分析:

  容易了解并操作,但是程式的擴充性不好,且耦合性強(将産品與建立産品的過程封裝在一起)。

(5)UML圖

建立型設計模式 -- 建造者模式

二、建造者模式

1、什麼是建造者模式

  又叫生成器模式,其将複雜的對象的建造過程抽象出來,并在其子類中去實作不同的建造。使用者隻需要去調用就行,不需要管建造的内部細節如何實作。簡單的了解為,将一堆零件拼成一個整體,而零件是抽象的,并由不同的子類去實作,使用者不需要管零件是如何形成的,能組裝就行。

2、建造者模式的核心角色

(1)産品(Product):一個具體的産品對象。

(2)抽象建造者(Builder):定義一個接口或抽象類,内部定義生成産品各個零件的抽象方法。

(3)具體建造者(ConcreateBuilder):實作接口,并重寫生成各零件的方法。

(4)組裝者(Commander):按照流程拼接零件,并傳回一個對象。

(5)代碼實作:

package builder.pattern;/**
 * 測試類
 * */public class BuilderDemo {    public static void main(String[] args) {
        System.out.println("建别墅流程:");
        HouseBuilder villaBuilder = new VillaBuilder();
        HouseCommandar villaCommandar = new HouseCommandar(villaBuilder);
        System.out.println(villaCommandar.createHouse());

        System.out.println("\n建高樓流程");
        HouseBuilder highBuildBuilder = new HighBuildBuilder();
        HouseCommandar highBuildCommandar = new HouseCommandar(highBuildBuilder);
        System.out.println(highBuildCommandar.createHouse());
    }
}/**
 * 産品類
 * */class House {    private String basis;    private String wall;    private String roof;    public String getBasis() {        return basis;
    }    public void setBasis(String basis) {        this.basis = basis;
    }    public String getWall() {        return wall;
    }    public void setWall(String wall) {        this.wall = wall;
    }    public String getRoof() {        return roof;
    }    public void setRoof(String roof) {        this.roof = roof;
    }

    @Override    public String toString() {        return "House [basis=" + basis + ", wall=" + wall + ", roof=" + roof + "]";
    }
}/**
 * 抽象建造者,内部定義生成産品各個零件的抽象方法。
 * */abstract class HouseBuilder {
    House house = new House();    public abstract void scoopHole(); // 挖地基

    public abstract void buildWall(); // 砌牆

    public abstract void topOff(); // 封頂

    public House getHouse() {        return house;
    }
}/**
 * 具體建造者,建别墅,繼承抽象類,并重寫相關方法
 * */class VillaBuilder extends HouseBuilder {
    @Override    public void scoopHole() {
        house.setBasis("挖10米地基");
    }

    @Override    public void buildWall() {
        house.setWall("砌10層牆");
    }

    @Override    public void topOff() {
        house.setRoof("樓頂建個遊泳池");
    }
}/**
 * 建高樓流程,實作建房子的接口
 * */class HighBuildBuilder extends HouseBuilder {

    @Override    public void scoopHole() {
        house.setBasis("挖30米地基");
    }

    @Override    public void buildWall() {
        house.setWall("砌60層牆");
    }

    @Override    public void topOff() {
        house.setRoof("樓頂建個停機坪");
    }
}/**
 * 組裝者,控制零件組合流程,并傳回一個産品對象 */class HouseCommandar {    private HouseBuilder houseBuilder;    /**
     * 擷取具體的建造者     */
    public HouseCommandar(HouseBuilder houseBuilder) {        this.houseBuilder = houseBuilder;
    }    /**
     * 控制建房流程,并傳回一個房子執行個體
     * 
     * @return 房子執行個體     */
    public House createHouse() {
        houseBuilder.scoopHole();
        houseBuilder.buildWall();
        houseBuilder.topOff();        return houseBuilder.getHouse();
    }
}      

(6)代碼分析:

  相比于上例,其将控制産品流程的代碼抽出來了。使産品與産品建構流程分離,進而在一定程度上解耦。當擴充代碼時,隻需繼承HouseBuilder 并重寫相關方法即可。

(7)UML圖:

建立型設計模式 -- 建造者模式

3、抽象工廠模式與建造者模式的差別

(1)抽象工廠模式是根據不同的工廠去建立一個對象。

(2)建造者模式是根據流程去組裝一個對象。

三、JDK源碼分析(StringBuilder)

1、部分源碼

public final class StringBuilder extends AbstractStringBuilder implements java.io.Serializable, CharSequence{
    
}abstract class AbstractStringBuilder implements Appendable, CharSequence{    //内部定義了一系列方法,且部分方法傳回值類型為AbstractStringBuilder 
    public AbstractStringBuilder append(String str) {        if (str == null)            return appendNull();        int len = str.length();
        ensureCapacityInternal(count + len);
        str.getChars(0, len, value, count);
        count += len;        return this;
    }     public AbstractStringBuilder deleteCharAt(int index) {        if ((index < 0) || (index >= count))            throw new StringIndexOutOfBoundsException(index);
        System.arraycopy(value, index+1, value, index, count-index-1);
        count--;        return this;
    }
}      

2、源碼分析

繼續閱讀