欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

创建模式 -- 建造者模式

程序员文章站 2022-05-18 21:24:59
一、小案例分析 1、功能需求: 现需要建房子,建房流程:挖地基、砌墙、封顶。对于不同种类的房子(高楼,别墅),流程虽然一样,但是具体功能实现不同。如何实现建房子? 2、小菜鸡的答案: (1)定义一个抽象接口,并定义三个抽象方法(挖地基、砌墙、封顶)。(2)对于不同种类的房子,实现该接口,并重写相关方 ......

一、小案例分析

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

  abstractstringbuilder 内部定义了一系列返回值类型为abstractstringbuilder 的方法,这些方法可以组合起来,形成链式调用(产品构建流程),根据链式调用来组装成最后返回的对象。
即stringbuilder 是组装者与具体建造者。abstractstringbuilder 是抽象建造者。