天天看点

创建型设计模式 -- 建造者模式

   创建型设计模式 -- 建造者模式

一、小案例分析

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、源码分析

继续阅读