建造者模式

建造者模式介绍:

 1)建造者模式(Builder Pattern)又叫生成器模式,是一种创建型模式。它可以将复杂对象的建造过程抽象出来,使这个抽象过程的不同实现方法可以构建出不同表现的对象

2)建造者模式是一步一步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建他们,用户不需要知道具体的构建细节

 

建造模式的四个角色:

  1. Product(产品角色):一个具体的产品对象
  2. Builder(抽象建造者):创建一个Product对象的各个部件指定的接口
  3. ConCreateBuilder(具体创建者):实现接口,构建和装配各个部件
  4. Director(指挥者):构建一个使用Builder接口的对象,它主要用于创建一个复杂的对象。它主要有两个作用:一是隔离了客户与对象的生产过程;二是负责控制产品对象的生产过程

 

提一个需求:

  盖房项目需求:

  1. 建房子的过程:打地基,砌墙,封顶
  2. 房子的种类有很多:比如我要建造普通房,高楼,别墅

 

不考虑模式试着自己写下

UML类图

建造者模式_第1张图片

 

代码

房屋抽象类和子类

package com.zjh.designmodel.builder;

/**
 * @Author: zjh
 * @Description:
 * @Date: Created in 2020/5/20 20:16
 * Modified by:
 */
public abstract class AbstractHouse {
    abstract void bulderBasic();
    abstract void bulderWalls();
    abstract void roofs();
}
package com.zjh.designmodel.builder;

/**
 * @Author: zjh
 * @Description:
 * @Date: Created in 2020/5/20 20:17
 * Modified by:
 */
public class CommonRoom extends AbstractHouse {
    @Override
    void bulderBasic() {
        System.out.println("普通房子地基打5米");
    }

    @Override
    void bulderWalls() {
        System.out.println("普通房子砌墙3厘米");
    }

    @Override
    void roofs() {
        System.out.println("普通房子封顶了");
    }

    public void builder(){
        bulderBasic();
        bulderWalls();
        roofs();
    }
}
package com.zjh.designmodel.builder;

/**
 * @Author: zjh
 * @Description:
 * @Date: Created in 2020/5/20 20:18
 * Modified by:
 */
public class TallBuilder extends AbstractHouse {
    @Override
    void bulderBasic() {
        System.out.println("高楼打地基7米");
    }

    @Override
    void bulderWalls() {
        System.out.println("高楼砌墙5厘米");
    }

    @Override
    void roofs() {
        System.out.println("高楼封顶了");
    }
    public void builder(){
        bulderBasic();
        bulderWalls();
        roofs();
    }
}
package com.zjh.designmodel.builder;

/**
 * @Author: zjh
 * @Description:别墅类
 * @Date: Created in 2020/5/20 20:19
 * Modified by:
 */
public class Villa  extends AbstractHouse{
    @Override
    void bulderBasic() {
        System.out.println("别墅打地基9米");
    }

    @Override
    void bulderWalls() {
        System.out.println("别墅砌墙10厘米");
    }

    @Override
    void roofs() {
        System.out.println("别墅封顶了");
    }

    public void builder(){
        bulderBasic();
        bulderWalls();
        roofs();
    }
}

测试

建造者模式_第2张图片

优点:

比较好理解,简单易操作

缺点:

设计的程序结构过于简单,没有设计缓存层对象,程序的扩展和维护不好,也就是说这种设计方案是吧产品(房子)和创建产品的过程(打地基、砌墙、封顶)放在了一起,耦合性增强。建造者模式就是为了把产品和创建产品的过程进行解耦

 

建造者模式思路

1.我们先创建一个产品类(HouseProduct),让其拥有地基、墙面、屋顶的属性

2.创建一个抽象建造者(可以理解为房地产公司),让其拥有房屋这个属性并且拥有打地基、砌墙、盖屋顶和创建房子的抽象方法(可以理解为房地产公司只负责说自己可以建造哪些房子,但是没有具体的房子)

3.然后在创建具体的房子构建者(可以理解为房地产公司的建房子的部门,他们负责建造具体的房子)

4.最后在创建指挥类(可以理解为包工头,他负责房子的具体建造顺序----比如普通房子地基不是很深,我们可以吧运砖快和打地基同时进行,但是高楼必须先打地基)

 

原型模式UML类图

建造者模式_第3张图片

 

修改后的代码

产品类

package com.zjh.designmodel.builder.designmodelbuilder.product;

import lombok.Data;

/**
 * @Author: zjh
 * @Description:
 * @Date: Created in 2020/5/22 18:19
 * Modified by:
 */
@Data
public class HouseProduct {
    private String basic;//地基
    private String walls;//墙面
    private String roofs;//屋顶
}

抽象建造者和他的具体实现类

package com.zjh.designmodel.builder.designmodelbuilder.builder;

import com.zjh.designmodel.builder.designmodelbuilder.product.HouseProduct;

/**
 * @Author: zjh
 * @Description:
 * @Date: Created in 2020/5/22 18:20
 * Modified by:
 */
public abstract class AbstractBuilder {
    HouseProduct houseProduct=new HouseProduct();
    public abstract void  bulderBasic();
    public abstract void  bulderWalls();
    public abstract void roofs();
    public abstract HouseProduct createHouse();
}
package com.zjh.designmodel.builder.designmodelbuilder.builder;

import com.zjh.designmodel.builder.designmodelbuilder.product.HouseProduct;

/**
 * @Author: zjh
 * @Description:
 * @Date: Created in 2020/5/22 18:22
 * Modified by:
 */
public class CommonRoomBuilder extends AbstractBuilder {
    @Override
    public void bulderBasic() {
        System.out.println("普通房子地基打5米");
    }

    @Override
    public void bulderWalls() {
        System.out.println("普通房子墙面10厘米");
    }

    @Override
    public void roofs() {
        System.out.println("普通房子进行封顶");
    }

    @Override
    public HouseProduct createHouse() {
        HouseProduct houseProduct = super.houseProduct;
        houseProduct.setBasic("5米");
        houseProduct.setRoofs("10厘米");
        houseProduct.setRoofs("普通房子屋顶");
        return houseProduct;
    }
}
package com.zjh.designmodel.builder.designmodelbuilder.builder;

import com.zjh.designmodel.builder.designmodelbuilder.product.HouseProduct;

/**
 * @Author: zjh
 * @Description:
 * @Date: Created in 2020/5/22 18:25
 * Modified by:
 */
public class TallBuilder extends AbstractBuilder {
    @Override
    public void bulderBasic() {
        System.out.println("高楼地基15米");
    }

    @Override
    public void bulderWalls() {
        System.out.println("高楼墙面30厘米");
    }

    @Override
    public void roofs() {
        System.out.println("高楼封顶");
    }

    @Override
    public HouseProduct createHouse() {
        HouseProduct houseProduct = super.houseProduct;
        houseProduct.setBasic("15米");
        houseProduct.setWalls("30厘米");
        houseProduct.setRoofs("高楼封顶");
        return houseProduct;
    }
}
package com.zjh.designmodel.builder.designmodelbuilder.builder;

import com.zjh.designmodel.builder.designmodelbuilder.product.HouseProduct;

/**
 * @Author: zjh
 * @Description:
 * @Date: Created in 2020/5/22 18:31
 * Modified by:
 */
public class VillaBuilder extends AbstractBuilder {
    @Override
    public void bulderBasic() {
        System.out.println("别墅地基10米");
    }

    @Override
    public void bulderWalls() {
        System.out.println("别墅墙面20厘米");
    }

    @Override
    public void roofs() {
        System.out.println("别墅封顶");
    }

    @Override
    public HouseProduct createHouse() {
        HouseProduct houseProduct = super.houseProduct;
        houseProduct.setBasic("10米");
        houseProduct.setWalls("20厘米");
        houseProduct.setRoofs("别墅封顶");
        return houseProduct;
    }
}

指挥类

package com.zjh.designmodel.builder.designmodelbuilder;

import com.zjh.designmodel.builder.designmodelbuilder.builder.AbstractBuilder;
import com.zjh.designmodel.builder.designmodelbuilder.builder.CommonRoomBuilder;
import com.zjh.designmodel.builder.designmodelbuilder.builder.TallBuilder;
import com.zjh.designmodel.builder.designmodelbuilder.builder.VillaBuilder;
import com.zjh.designmodel.builder.designmodelbuilder.product.HouseProduct;

/**
 * @Author: zjh
 * @Description:
 * @Date: Created in 2020/5/22 18:33
 * Modified by:
 */
public class Director {
    private AbstractBuilder abstractBuilder;
    public Director(AbstractBuilder abstractBuilder){
        this.abstractBuilder=abstractBuilder;
    }
    public HouseProduct getCommonHouse() throws InterruptedException {
        CommonRoomBuilder commonRoomBuilder= (CommonRoomBuilder) abstractBuilder;
        //建造普通房子 地基和运砖的顺序可以同时,因为地基不是很深
        commonRoomBuilder.bulderWalls();
        commonRoomBuilder.bulderBasic();
        Thread.sleep(500);
        commonRoomBuilder.roofs();
        return commonRoomBuilder.createHouse();
    }

    public HouseProduct getTailHouse() throws InterruptedException {
        TallBuilder tallBuilder= (TallBuilder) abstractBuilder;
        //建造高楼要先打地基
        tallBuilder.bulderBasic();
        Thread.sleep(500);
        tallBuilder.bulderWalls();
        Thread.sleep(500);
        tallBuilder.roofs();
        return tallBuilder.createHouse();
    }

    public HouseProduct getVillaHouse() throws InterruptedException {
        VillaBuilder villaBuilder= (VillaBuilder) abstractBuilder;
        //建造别墅
        villaBuilder.bulderBasic();
        Thread.sleep(500);
        villaBuilder.bulderWalls();
        Thread.sleep(500);
        villaBuilder.roofs();
        return villaBuilder.createHouse();
    }
}

测试

建造者模式_第4张图片

 

改造后的优点:

  • 使用建造者模式可以使客户端不必知道产品内部组成的细节。
  • 具体的建造者类之间是相互独立的,这有利于系统的扩展。
  • 具体的建造者相互独立,因此可以对建造的过程逐步细化,而不会对其他模块产生任何影响

 

改造后的缺点:

  • 建造者模式所创建的产品一般具有较多的共同点,其组成部分相似;如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制。
  • 如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大。

 

JDK源码(StringBuilder)

建造者模式_第5张图片

AbstractStringBuilder我们可以理解为抽象抽象建造者,StringBuilder可以理解为具体的施工者(StringBuilder这里吧社施工者和产品放在了一起),我们通过StringBuilder的append方法添加各种类型的数据到StringBuilder,然后StringBuilder在返给我们一个StringBuilder类型的字符串,可以把我们自己看成指挥者

 

 写完这些以后是不是发现和前面讲的工厂模式差不多,下面我们来了解下建造者模式和工厂模式的区别

  • 与抽象工厂模式相比,建造者模式返回一个组装好的完整产品,而抽象工厂模式返回一系列相关的产品,这些产品位于不同的产品等级结构,构成了一个产品族 。
  • 在抽象工厂模式中,客户端实例化工厂类,然后调用工厂方法获取所需产品对象,而在建造者模式中,客户端可以不直接调用建造者的相关方法,而是通过指挥者类来指导如何生成对象,包括对象的组装过程和建造步骤,它侧重于一步步构造一个复杂对象,返回一个完整的对象 。
  • 如果将抽象工厂模式看成汽车配件生产工厂,生产一个产品族的产品,那么建造者模式就是一个汽车组装工厂,通过对部件的组装可以返回一辆完整的汽车

 

 

 

你可能感兴趣的:(设计模式)