Welcome everyone

一文搞懂建造者模式

设计模式 汪明鑫 13浏览 0评论

前言

建造者模式顾名思义造东西的,因此是创建型设计模式

建房子需要打地基、砌墙、封顶

地基、砌墙、封顶都是建房子的必须的一部分,固定的建造部分组成整体

就可以使用建造者模式

过程和建造房子的部分相同,但不同的房子建造的高度质量等不太一样

 

通用类图

 

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

 

 

盖房子-代码

具体产品-房子

/**
 * 具体创建产品
 *
 * @author wmx
 * @date 2019-08-21
 */
@Data
public class House {
    private String foundation; //地基
    private String wall; //墙
    private String roof; //房顶
}

 

/**
 * 抽象建造者
 *
 * @author wmx
 * @date 2019-08-21
 */
public  abstract class  Builder{

    protected House house = new House();

    abstract void foundation();

    abstract void wall();

    abstract void roof();

    abstract House createHouse();
}
/**
 * 草屋具体建造者
 *
 * @author wmx
 * @date 2019-08-21
 */
public class CottageBuilder extends Builder{
    @Override
    void foundation() {
        house.setFoundation("没地基");
    }

    @Override
    void wall() {
        house.setWall("木墙");
    }

    @Override
    void roof() {
        house.setRoof("草房顶");
    }

    @Override
    House createHouse() {
        return house;
    }
}
/**
 * 高楼具体建造者
 *
 * @author wmx
 * @date 2019-08-21
 */
public class HighBuildingsBuilder extends Builder{

    @Override
    void foundation() {
        house.setFoundation("地基深");
    }

    @Override
    void wall() {
        house.setWall("墙厚");
    }

    @Override
    void roof() {
        house.setRoof("房顶好");
    }

    @Override
    House createHouse() {
        return house;
    }
}
/**
 * 包工头 指挥建房
 *
 * @author wmx
 * @date 2019-08-21
 */
public class LabourContractor {
    private Builder builder;

    public LabourContractor(Builder builder){
        this.builder = builder;
    }

    House build(){
        builder.foundation();
        builder.wall();
        builder.roof();
        return builder.createHouse();
    }
}

 

public class Client {
    public static void main(String[] args) {
        LabourContractor labourContractor = new LabourContractor(new CottageBuilder());
        House cottage = labourContractor.build();
        System.out.println(cottage);

        //又来了批有钱的包工头,把这里改成开发区
        LabourContractor labourContractor1 = new LabourContractor(new HighBuildingsBuilder());
        House highBuildings = labourContractor1.build();
        System.out.println(highBuildings);
    }
}

输出:

House(foundation=没地基, wall=木墙, roof=草房顶)
House(foundation=地基深, wall=墙厚, roof=房顶好)

 

分析

客户端依赖指挥者,指挥者传入具体的builder即可建造对象,

屏蔽了建造的过程和具体的细节,很好的解藕

个人感觉建造者模式有点像模版方法模式,也是以一个模版,一定的步骤来建造;

类似工厂模式,屏蔽细节流程进行建造

 

用户使用不同的具体建造者即可得到不同的产品对象

可以更加细致的控制产品的创建过程

 

可以把建造者模式理解成一步步构建小的部分,组成大的部分

 

建造者模式不适用的场景

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

 

建造者模式 VS 抽象工厂模式

抽象工厂模式实现对产品家族的创建,一个产品家族是这样的一系列产品:具有不
同分类维度的产品组合,采用抽象工厂模式不需要关心构建过程,只关心什么产品
由什么工厂生产即可。而建造者模式则是要求按照指定的蓝图建造产品,它的主要
目的是通过组装零配件而产生一个新产品(一定的流程把部分构建成整体)

 

StringBuilder

public static void main(String[] args) {
        StringBuilder builder = new StringBuilder();
        builder.append("hello");
        builder.append("world");
        builder.append("!!!");
    }

 

 

Lombok @Builder

lombok有个注解 @Builder

也有建造者模式的思想

 

/**
 * @author wmx
 * @date 2019-08-21
 */
@Data
@Builder
public class House {
    private String foundation;
    private String wall;
    private String roof; 
}
public static void main(String[] args) {

        House myhouse = House.builder()
                .foundation("好地基")
                .wall("好墙")
                .roof("好房顶")
                .build();
        System.out.println(myhouse);
    }

分析:

获取House的建造者,

客户端直接指定建造部分的流程,build()就是获取建造结果

 

如何实现@Builder的功能:

模拟一把

/**
 * 模拟@Builder的功能
 *
 * @author wmx
 * @date 2019-08-21
 */
@Data
public class House {

    public static HouseBuilder builder = new HouseBuilder();

    private String foundation;
    private String wall;
    private String roof;

    static class HouseBuilder{
        House house = new House();
        HouseBuilder foundation(String foundation){
            house.setFoundation(foundation);
            return builder;
        }

        HouseBuilder wall(String wall){
            house.setWall(wall);
            return builder;
        }

        HouseBuilder roof(String roof){
            house.setRoof(roof);
            return builder;
        }

        House build(){
            return house;
        }
    }
}
public static void main(String[] args) {
        House house = House.builder
                .foundation("一级地基")
                .wall("一级墙")
                .roof("一级房顶")
                .build();
        
        System.out.println(house);
    }

 

把具体产品和建造者合到一起

建造者以静态内部类的形式

同样可以封装具体的细节

建造部分最后build构成整体

这里的建造流程在客户端指定

可以理解成指挥者为产品使用者

 

如有错误的代码和理解,敬请指正=-=

 

 

 

转载请注明:汪明鑫的个人博客 » 一文搞懂建造者模式

喜欢 (0)

说点什么

您将是第一位评论人!

提醒
avatar
wpDiscuz