Skip to content

一、构建者模式是什么?

  • 在软件开发过程中有时需要创建一个复杂的对象,这个复杂对象通常由多个子部件按一定的步骤组合而成。例如,计算机是由 OPU、主板、内存、硬盘、显卡、机箱、显示器、键盘、鼠标等部件组装而成的,采购员不可能自己去组装计算机,而是将计算机的配置要求告诉计算机销售公司,计算机销售公司安排技术人员去组装计算机,然后再交给要买计算机的采购员。

  • 生活中这样的例子很多,如游戏中的不同角色,其性别、个性、能力、脸型、体型、服装、发型等特性都有所差异;还有汽车中的方向盘、发动机、车架、轮胎等部件也多种多样;每封电子邮件的发件人、收件人、主题、内容、附件等内容也各不相同。

以上所有这些产品都是由多个部件构成的,各个部件可以灵活选择,但其创建步骤都大同小异。这类产品的创建无法用前面介绍的工厂模式描述,只有建造者模式可以很好地描述该类产品的创建。

构建者模式 (Builder Pattern):

  • 指将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示。

  • 它是将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成。

  • 它将变与不变相分离,即产品的组成部分是不变的,但每一部分是可以灵活选择的。

  • 这属于创建型模式。


二、为什么要使用构建者模式 ?

作用:主要解决在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。


三、构建者模式应用场景有哪些 ?

  • 去肯德基,汉堡、可乐、薯条、炸鸡翅等是不变的,而其组合是经常变化的,生成出所谓的"套餐"。
  • JAVA 中的 StringBuilder。
  • Lombok 中 @Build 注解。

四、如何实现构建者模式?

模式的结构

1. 抽象产品类 Computer。

2. Builder 抽象 Builder,规范产品的组建,一般是由子类实现具体的组建过程。

3. MacbookBuilder 具体的 Builder 类,具体的创建对象的类。

4. Directror(监督者) 统一组建过程。


6. 案例 1:组装一台计算机为主

以组装一台计算机为主,主要进行组装主机,设置操作系统,设置显示器。

1. 计算机抽象类 Computer

  • 抽象出计算机共同属性和行为:主板、显示器、操作系统
java
package com.computer.abstracts;

import lombok.ToString;

/**
 * description: 计算机(抽象产品类)
 * date: 2020/9/10 16:51
 * author: Calvino
 * version: 1.0
 */
@ToString
public abstract class Computer {

    public Computer() {
    }

    /**
     * 主机
     */
    protected String board;

    /**
     * 显示器
     */
    protected String display;

    /**
     * 操作系统
     */
    protected String os;

    /**
     * 设置主机
     *
     * @param board 主机
     */
    public void setBoard(String board) {
        this.board = board;
    }

    /**
     * 设置显示器
     * @param display 显示器
     */
    public void setDisplay(String display) {
        this.display = display;
    }

    /**
     *  设置操作系统
     */
    public abstract void setOs();

}

2. 具体产品类 MacBookServiceImpl、WindowsBookSeriveImpl

  • 不同的计算机继承父类,实现不同的操作系统。
java
package com.computer.service.impl;

import com.computer.abstracts.Computer;

/**
 * description: 苹果电脑-具体实现类
 * date: 2020/9/10 16:55
 * author: Calvin
 * version: 1.0
 */
public class MacBookServiceImpl extends Computer {

    @Override
    public void setOs() {
        os = "Mac OS X 12";
        System.out.println(os);
    }

}
java
package com.computer.service.impl;

import com.computer.abstracts.Computer;

/**
 * description: Window电脑-具体实现类
 * date: 2020/9/10 16:55
 * author: Calvin
 * version: 1.0
 */
public class WindowsBookServiceImpl extends Computer {

    @Override
    public void setOs() {
        os = "Windows 10";
        System.out.println(os);
    }

}

3. 抽象 Builder

  • 规范产品的组建
java
package com.computer.abstracts;

/**
 * description: Builder
 * date: 2020/9/10 17:03
 * author: Calvin
 * version: 1.0
 */
public abstract class Builder {

    /**
     * 构建主机
     * @param board 主机
     */
    public abstract void buildBoard(String board);

    /**
     * 构建显示器
     * @param display 显示器
     */
    public abstract void buildDisplay(String display);

    /**
     * 构建操作系统
     */
    public abstract void buildOs();

    /**
     * 整体主装
     * @return 完整的计算机
     */
    public abstract Computer build();

}

4. 具体的 Builder 类有 MacBookBuilder、WindowsBookBuilder

  • 实现规范产品的组建具体过程。
java
package com.computer.builder;

import com.computer.abstracts.Builder;
import com.computer.abstracts.Computer;
import com.computer.service.impl.MacBookServiceImpl;

/**
 * description: MacBookBuilder
 * date: 2020/9/10 17:07
 * author: Calvin
 * version: 1.0
 */
public class MacBookBuilder extends Builder {

    private Computer computer;

    public MacBookBuilder (){
        computer = new MacBookServiceImpl();
    }

    @Override
    public void buildBoard(String board) {
        computer.setBoard(board);
    }

    @Override
    public void buildDisplay(String display) {
        computer.setDisplay(display);
    }

    @Override
    public void buildOs() {
        computer.setOs();
    }

    @Override
    public Computer build() {
        return computer;
    }

}
java
package com.computer.builder;

import com.computer.abstracts.Builder;
import com.computer.abstracts.Computer;
import com.computer.service.impl.MacBookServiceImpl;

/**
 * description: MacBookBuilder
 * date: 2020/9/10 17:07
 * author: Calvin
 * version: 1.0
 */
public class MacBookBuilder extends Builder {

    private Computer computer;

    public MacBookBuilder (){
        computer = new MacBookServiceImpl();
    }

    @Override
    public void buildBoard(String board) {
        computer.setBoard(board);
    }

    @Override
    public void buildDisplay(String display) {
        computer.setDisplay(display);
    }

    @Override
    public void buildOs() {
        computer.setOs();
    }

    @Override
    public Computer build() {
        return computer;
    }

}

5. Director 类,负责具体的构造 Computer

  • Directror(监督者) 统一组建过程。
java
package com.computer.builder;

import com.computer.abstracts.Builder;

/**
 * description: Director
 * date: 2020/9/10 17:22
 * author: Calvin
 * version: 1.0
 */
public class Director {

    Builder builder = null;

    /**
     * 初始化构造函数
     * @param builer 构建抽象类
     */
    public Director(Builder builer) {
        this.builder = builer;
    }

    /**
     * 统一组建构建:主机、显示器、操作系统
     * @param board 主机
     * @param display 显示器
     */
    public void construct(String board,String display){
        builder.buildDisplay(display);
        builder.buildBoard(board);
        builder.buildOs();
    }

}

6. 具体调用过程

  • 根据请求 OS 参数,获取对应的 Buidler 组建过程。
  • 再通过具体的 Builder, 通过使用 Director 监督者进行组装。
  • 最后,组装完成,通过 Builder 中的 build 方法,获取到主装后的完整计算机。
java
package com.computer.service.impl;

import com.computer.abstracts.Builder;
import com.computer.abstracts.Computer;
import com.computer.builder.Director;
import com.computer.enumeration.ComputerBuildEnum;
import com.computer.service.ComputerService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

/**
 * description: ComputerServiceImpl
 * date: 2020/9/10 17:29
 * author: Calvin
 * version: 1.0
 */
@Slf4j
@Service
public class ComputerServiceImpl implements ComputerService {

    @Override
    public Computer build(String os) {
        Computer computer = null;
        try {
            ComputerBuildEnum computerBuildEnum = ComputerBuildEnum.valueOf(os);
            String builderBeanName = computerBuildEnum.getBuilderBeanName();
            Class<?> builderClass = Class.forName(builderBeanName);
            Builder builder = (Builder) builderClass.newInstance();
            // 1. 实例监督者,进行组装电脑
            Director director = new Director(builder);
            director.construct("英特尔主板","Retina显示器");
            // 2. 组装后,通过构建者获取对应的电脑
            computer = builder.build();
        } catch (Exception e) {
            log.error("错误的原因:{}", e.getMessage());
            throw new RuntimeException("没有该" + os + "操作系统");
        }
        return computer;
    }
}

7. 演示测试

代码链接:https://github.com/1016280226/design-patterns

1. 通过访问

GET http://localhost:8080/computer/build?os=MAC_BUILD

GET http://localhost:8080/computer/build?os=WINDOWS_BUILD

2. 输出结果

verilog
Computer(board=英特尔主板, display=Retina显示器, os=Mac OS X 12)
Computer(board=英特尔主板, display=Retina显示器, os=Windows 10)

8. 优缺点


9. 建造者和工厂-区别

区别:建造者模式更加关注与零件装配的顺序。