Java建造者模式(Builder Pattern)详解与实践

一、引言

在软件开发中,我们经常会遇到需要创建复杂对象 的场景。例如,构建一个包含多个可选参数的对象时,传统的构造函数或Setter方法可能导致代码臃肿、难以维护。此时,建造者模式(Builder Pattern)便成为一种优雅的解决方案。它通过分步骤构建对象,将对象的创建过程与其表示分离,从而提高代码的可读性和可维护性。


二、什么是建造者模式?

建造者模式(Builder Pattern)是一种创建型设计模式,其核心思想是通过分步骤构造复杂对象,最终返回一个完整的产品。它允许相同的构建过程创建不同的表示,同时避免构造函数参数过多的问题。

例如:Person person1=new Person(10个参数)

如果只需要其中3个的话,就得提供一个3个参数的构造函数

1.核心角色

  1. Product(产品):最终构建的复杂对象。
  2. Builder(抽象建造者):定义构建产品的抽象步骤。
  3. ConcreteBuilder(具体建造者):实现Builder接口,完成具体构建逻辑。
  4. Director(指挥者,可选):控制构建流程,协调建造者的步骤。

2.适用场景

  • 创建包含多个部件的复杂对象(如配置类、HTTP请求对象)。
  • 需要控制对象的创建过程(分步骤构建)。
  • 需要构建不同表示的对象(相同构建过程,不同实现)。
  • 希望避免构造器参数过多(解决"伸缩构造函数"问题)。

三、代码示例:

1.电脑

⑴.产品 (Product)Computer类表示要构建的电脑

产品提供每个字段的set方法

复制代码
// 产品类:电脑
public class Computer {
    private String cpu;
    private String memory;
    private String hardDisk;
    private String graphicsCard;
    private String monitor;
    private String keyboard;
    private String mouse;

    public void setCpu(String cpu) {
        this.cpu = cpu;
    }

    public void setMemory(String memory) {
        this.memory = memory;
    }

    public void setHardDisk(String hardDisk) {
        this.hardDisk = hardDisk;
    }

    public void setGraphicsCard(String graphicsCard) {
        this.graphicsCard = graphicsCard;
    }

    public void setMonitor(String monitor) {
        this.monitor = monitor;
    }

    public void setKeyboard(String keyboard) {
        this.keyboard = keyboard;
    }

    public void setMouse(String mouse) {
        this.mouse = mouse;
    }

    @Override
    public String toString() {
        return "Computer{" +
                "cpu='" + cpu + '\'' +
                ", memory='" + memory + '\'' +
                ", hardDisk='" + hardDisk + '\'' +
                ", graphicsCard='" + graphicsCard + '\'' +
                ", monitor='" + monitor + '\'' +
                ", keyboard='" + keyboard + '\'' +
                ", mouse='" + mouse + '\'' +
                '}';
    }
}    

⑵.抽象建造者 (Builder)ComputerBuilder接口定义了构建电脑各部分的方法

接口定义二次封装的构建方法

复制代码
// 抽象建造者接口
public interface ComputerBuilder {
    void buildCPU();
    void buildMemory();
    void buildHardDisk();
    void buildGraphicsCard();
    void buildMonitor();
    void buildKeyboard();
    void buildMouse();
    Computer getComputer();
}    

⑶.具体建造者 (ConcreteBuilder)

GamingComputerBuilderOfficeComputerBuilder实现了抽象接口

复制代码
// 具体建造者:游戏电脑建造者
public class GamingComputerBuilder implements ComputerBuilder {
    private Computer computer = new Computer();

    @Override
    public void buildCPU() {
        computer.setCpu("Intel i9-12900K");
    }

    @Override
    public void buildMemory() {
        computer.setMemory("32GB DDR5 5200MHz");
    }

    @Override
    public void buildHardDisk() {
        computer.setHardDisk("2TB NVMe SSD");
    }

    @Override
    public void buildGraphicsCard() {
        computer.setGraphicsCard("NVIDIA RTX 4090");
    }

    @Override
    public void buildMonitor() {
        computer.setMonitor("4K 144Hz Gaming Monitor");
    }

    @Override
    public void buildKeyboard() {
        computer.setKeyboard("Mechanical Gaming Keyboard");
    }

    @Override
    public void buildMouse() {
        computer.setMouse("High Precision Gaming Mouse");
    }

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

复制代码
// 具体建造者:办公电脑建造者
public class OfficeComputerBuilder implements ComputerBuilder {
    private Computer computer = new Computer();

    @Override
    public void buildCPU() {
        computer.setCpu("Intel i5-12400");
    }

    @Override
    public void buildMemory() {
        computer.setMemory("16GB DDR4 3200MHz");
    }

    @Override
    public void buildHardDisk() {
        computer.setHardDisk("512GB NVMe SSD");
    }

    @Override
    public void buildGraphicsCard() {
        computer.setGraphicsCard("Integrated Graphics");
    }

    @Override
    public void buildMonitor() {
        computer.setMonitor("24-inch Full HD Monitor");
    }

    @Override
    public void buildKeyboard() {
        computer.setKeyboard("Wireless Keyboard");
    }

    @Override
    public void buildMouse() {
        computer.setMouse("Wireless Mouse");
    }

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

⑷.指挥者 (Director)

ComputerDirector控制构建过程的顺序

复制代码
// 指挥者:电脑装配指导
public class ComputerDirector {
    private ComputerBuilder computerBuilder;

    public ComputerDirector(ComputerBuilder computerBuilder) {
        this.computerBuilder = computerBuilder;
    }

    public void setComputerBuilder(ComputerBuilder computerBuilder) {
        this.computerBuilder = computerBuilder;
    }

    public Computer constructComputer() {
        computerBuilder.buildCPU();
        computerBuilder.buildMemory();
        computerBuilder.buildHardDisk();
        computerBuilder.buildGraphicsCard();
        computerBuilder.buildMonitor();
        computerBuilder.buildKeyboard();
        computerBuilder.buildMouse();
        return computerBuilder.getComputer();
    }
}    

⑸.测试

复制代码
// 演示程序
public class BuilderPatternDemo {
    public static void main(String[] args) {
        // 创建具体建造者
        ComputerBuilder gamingBuilder = new GamingComputerBuilder();
        ComputerBuilder officeBuilder = new OfficeComputerBuilder();

        // 创建指挥者并指定建造者
        ComputerDirector director = new ComputerDirector(gamingBuilder);

        // 构建游戏电脑
        Computer gamingComputer = director.constructComputer();
        System.out.println("游戏电脑配置:");
        System.out.println(gamingComputer);

        // 切换为办公电脑建造者
        director.setComputerBuilder(officeBuilder);

        // 构建办公电脑
        Computer officeComputer = director.constructComputer();
        System.out.println("\n办公电脑配置:");
        System.out.println(officeComputer);
    }
}    

2.建造一座房屋

以下是一个完整、简单且可运行的Java代码示例,演示如何通过建造者模式构建一个House对象。

⑴. 产品类(Product)

复制代码
public class House {
    private final String walls;
    private final String roof;
    private final String windows;

    // 私有构造函数,防止外部直接创建
    private House(Builder builder) {
        this.walls = builder.walls;
        this.roof = builder.roof;
        this.windows = builder.windows;
    }

    @Override
    public String toString() {
        return "House{" +
                "walls='" + walls + '\'' +
                ", roof='" + roof + '\'' +
                ", windows='" + windows + '\'' +
                '}';
    }

    // 静态内部类:建造者
    public static class Builder {
        private String walls;
        private String roof;
        private String windows;

        // 设置墙壁
        public Builder setWalls(String walls) {
            this.walls = walls;
            return this;
        }

        // 设置屋顶
        public Builder setRoof(String roof) {
            this.roof = roof;
            return this;
        }

        // 设置窗户
        public Builder setWindows(String windows) {
            this.windows = windows;
            return this;
        }

        // 构建并返回House对象
        public House build() {
            return new House(this);
        }
    }
}

⑵.客户端调用(直接使用建造者)

复制代码
public class Client {
    public static void main(String[] args) {
        // 使用建造者模式构建一座房屋
        House house = new House.Builder()
                .setWalls("Brick")
                .setRoof("Tile")
                .setWindows("Double Glazed")
                .build();

        System.out.println(house);
    }
}

⑶.可选:指挥者类(Director)

如果构建流程较为固定,可以通过Director类封装构建逻辑:

复制代码
public class Director {
    // 构建标准房屋
    public House constructStandardHouse() {
        return new House.Builder()
                .setWalls("Concrete")
                .setRoof("Asphalt")
                .setWindows("Single Glazed")
                .build();
    }

    // 构建豪华房屋
    public House constructLuxuryHouse() {
        return new House.Builder()
                .setWalls("Stone")
                .setRoof("Wood")
                .setWindows("Triple Glazed")
                .build();
    }
}

⑷.客户端调用(通过Director)

复制代码
public class ClientWithDirector {
    public static void main(String[] args) {
        Director director = new Director();
        House standardHouse = director.constructStandardHouse();
        House luxuryHouse = director.constructLuxuryHouse();

        System.out.println("Standard House: " + standardHouse);
        System.out.println("Luxury House: " + luxuryHouse);
    }
}

四、实际应用场景

建造者模式在Java生态中广泛应用于以下场景:

  • Java内置类StringBuilder的链式调用(如append()方法)。
  • 复杂对象构建:如HTTP请求对象、数据库查询构建器。
  • 配置类:例如,构建一个包含多个可选参数的配置对象。

五、总结

建造者模式通过分步骤构建复杂对象,将对象的创建过程与表示分离,解决了构造函数参数过多、代码臃肿的问题。通过链式调用和可选参数的支持,它提高了代码的可读性和可维护性。在实际开发中,无论是构建一个简单的房屋对象,还是处理复杂的业务需求,建造者模式都能提供清晰的解决方案。

相关推荐
杰哥技术分享几秒前
PHP Yii2 安装SQL Server扩展-MAC M4 Pro芯片
开发语言·php
大只鹅10 分钟前
WebSocket类明明注入了Bean,为什么报错为null
java·websocket
ChinaRainbowSea18 分钟前
9-2 MySQL 分析查询语句:EXPLAIN(详细说明)
java·数据库·后端·sql·mysql
时序数据说20 分钟前
Java类加载机制及关于时序数据库IoTDB排查
java·大数据·数据库·物联网·时序数据库·iotdb
wowocpp20 分钟前
rabbitmq 与 Erlang 的版本对照表 win10 安装方法
java·rabbitmq·erlang
风象南24 分钟前
SpringBoot基于Java Agent的无侵入式监控实现
java·spring boot·后端
快下雨了L27 分钟前
Lua现学现卖
开发语言·lua
崎岖Qiu30 分钟前
【Spring篇08】:理解自动装配,从spring.factories到.imports剖析
java·spring boot·后端·spring·面试·java-ee
belldeep37 分钟前
java:如何用 JDBC 连接 TDSQL 数据库
java·数据库·jdbc·tdsql
2301_1472583692 小时前
7月2日作业
java·linux·服务器