DukeDuke
主页
关于我们
主页
关于我们
  • Java

    • Java基础

      • 内存与磁盘
      • 进制转换
      • 数据存储
      • Java基本数据类型
      • HashMap
      • Java四大引用
    • JVM

      • 认识JVM
      • JVM类加载器
      • 运行时数据区
      • 执行引擎
      • 本地方法接口
      • 本地方法库
      • JVM垃圾回收
      • JVM性能监控
      • JVM调优
    • 设计模式
      • 单例模式
      • 工厂模式
      • 策略模式
      • 适配器模式
      • 建造者模式
      • 原型模式
      • 装饰器模式
      • 代理模式
      • 外观模式
      • 享元模式
      • 组合模式
      • 桥接模式
    • Java多线程

      • Java 线程基础详解
      • Java 线程池详解
      • Java ThreadLocal 详解
      • Java volatile 详解
      • Java 线程间通信详解
      • Java 线程安全详解
      • Java 线程调度详解
      • Java 线程优先级详解

      • Java 线程中断详解
      • Java 线程死锁详解
    • Java反射
    • Java 面试题

      • Java 基础概念面试题
      • Java 面向对象编程面试题
      • Java 集合框架面试题
      • Java 多线程与并发面试题
      • JVM 与内存管理面试题
      • Java I/O 与 NIO 面试题
      • Java 异常处理面试题
      • Java 反射与注解面试题
      • Java Spring 框架面试题
      • Java 数据库与 JDBC 面试题
      • Java 性能优化面试题
      • Java 实际项目经验面试题
      • Java 高级特性面试题
      • Java 面试准备建议

建造者模式

什么是建造者模式?

建造者模式(Builder Pattern)是一种创建型设计模式,它允许你分步骤构建复杂对象。就像搭积木一样,你可以一步一步地组装出最终的产品,而不需要一次性创建所有组件。

为什么使用建造者模式?

想象一下你要组装一台电脑:

  • 你可以选择不同的 CPU、内存、硬盘、显卡等组件
  • 每个组件都有多种选择
  • 最终组装出一台完整的电脑

建造者模式就是帮你管理这种复杂对象的创建过程,让代码更清晰、更易维护。

使用场景

  1. 复杂对象的创建:当对象有很多可选参数时
  2. 对象创建过程复杂:需要分步骤构建
  3. 不可变对象:创建后不允许修改的对象
  4. 参数验证:在创建过程中进行参数检查

示例一:电脑组装

让我们用一个电脑组装的例子来说明建造者模式:

// 产品类 - 电脑
public class Computer {
    private String cpu;
    private String memory;
    private String storage;
    private String graphicsCard;
    private String motherboard;

    // 私有构造函数,只能通过Builder创建
    private Computer() {}

    // Getter方法
    public String getCpu() { return cpu; }
    public String getMemory() { return memory; }
    public String getStorage() { return storage; }
    public String getGraphicsCard() { return graphicsCard; }
    public String getMotherboard() { return motherboard; }

    @Override
    public String toString() {
        return "Computer{" +
                "cpu='" + cpu + '\'' +
                ", memory='" + memory + '\'' +
                ", storage='" + storage + '\'' +
                ", graphicsCard='" + graphicsCard + '\'' +
                ", motherboard='" + motherboard + '\'' +
                '}';
    }

    // 静态内部Builder类
    public static class Builder {
        private Computer computer;

        public Builder() {
            computer = new Computer();
        }

        public Builder cpu(String cpu) {
            computer.cpu = cpu;
            return this;
        }

        public Builder memory(String memory) {
            computer.memory = memory;
            return this;
        }

        public Builder storage(String storage) {
            computer.storage = storage;
            return this;
        }

        public Builder graphicsCard(String graphicsCard) {
            computer.graphicsCard = graphicsCard;
            return this;
        }

        public Builder motherboard(String motherboard) {
            computer.motherboard = motherboard;
            return this;
        }

        public Computer build() {
            // 验证必要参数
            if (computer.cpu == null) {
                throw new IllegalArgumentException("CPU是必需的");
            }
            if (computer.memory == null) {
                throw new IllegalArgumentException("内存是必需的");
            }
            return computer;
        }
    }
}

// 使用示例
public class ComputerBuilderExample {
    public static void main(String[] args) {
        // 创建游戏电脑
        Computer gamingComputer = new Computer.Builder()
                .cpu("Intel i7-12700K")
                .memory("32GB DDR4")
                .storage("1TB NVMe SSD")
                .graphicsCard("RTX 4080")
                .motherboard("Z690")
                .build();

        System.out.println("游戏电脑: " + gamingComputer);

        // 创建办公电脑
        Computer officeComputer = new Computer.Builder()
                .cpu("Intel i5-12400")
                .memory("16GB DDR4")
                .storage("512GB SSD")
                .motherboard("B660")
                .build();

        System.out.println("办公电脑: " + officeComputer);
    }
}

示例二:披萨制作

再来看一个披萨制作的例子,展示如何用建造者模式制作不同口味的披萨:

// 披萨类
public class Pizza {
    private String size;
    private String crust;
    private String sauce;
    private List<String> toppings;
    private boolean extraCheese;
    private boolean spicy;

    private Pizza() {
        this.toppings = new ArrayList<>();
    }

    // Getter方法
    public String getSize() { return size; }
    public String getCrust() { return crust; }
    public String getSauce() { return sauce; }
    public List<String> getToppings() { return new ArrayList<>(toppings); }
    public boolean isExtraCheese() { return extraCheese; }
    public boolean isSpicy() { return spicy; }

    @Override
    public String toString() {
        return "Pizza{" +
                "size='" + size + '\'' +
                ", crust='" + crust + '\'' +
                ", sauce='" + sauce + '\'' +
                ", toppings=" + toppings +
                ", extraCheese=" + extraCheese +
                ", spicy=" + spicy +
                '}';
    }

    // Builder类
    public static class Builder {
        private Pizza pizza;

        public Builder() {
            pizza = new Pizza();
        }

        public Builder size(String size) {
            pizza.size = size;
            return this;
        }

        public Builder crust(String crust) {
            pizza.crust = crust;
            return this;
        }

        public Builder sauce(String sauce) {
            pizza.sauce = sauce;
            return this;
        }

        public Builder addTopping(String topping) {
            pizza.toppings.add(topping);
            return this;
        }

        public Builder extraCheese() {
            pizza.extraCheese = true;
            return this;
        }

        public Builder spicy() {
            pizza.spicy = true;
            return this;
        }

        public Pizza build() {
            // 验证必要参数
            if (pizza.size == null) {
                throw new IllegalArgumentException("披萨尺寸是必需的");
            }
            if (pizza.crust == null) {
                throw new IllegalArgumentException("披萨饼底是必需的");
            }
            if (pizza.sauce == null) {
                pizza.sauce = "番茄酱"; // 默认酱料
            }
            return pizza;
        }
    }
}

// 使用示例
public class PizzaBuilderExample {
    public static void main(String[] args) {
        // 制作夏威夷披萨
        Pizza hawaiianPizza = new Pizza.Builder()
                .size("大号")
                .crust("薄底")
                .sauce("番茄酱")
                .addTopping("火腿")
                .addTopping("菠萝")
                .addTopping("青椒")
                .extraCheese()
                .build();

        System.out.println("夏威夷披萨: " + hawaiianPizza);

        // 制作辣味披萨
        Pizza spicyPizza = new Pizza.Builder()
                .size("中号")
                .crust("厚底")
                .sauce("辣酱")
                .addTopping("香肠")
                .addTopping("辣椒")
                .addTopping("洋葱")
                .addTopping("蘑菇")
                .spicy()
                .build();

        System.out.println("辣味披萨: " + spicyPizza);
    }
}

示例三:HTTP 请求构建器

最后看一个更实用的 HTTP 请求构建器示例:

// HTTP请求类
public class HttpRequest {
    private String method;
    private String url;
    private Map<String, String> headers;
    private String body;
    private int timeout;
    private boolean followRedirects;

    private HttpRequest() {
        this.headers = new HashMap<>();
        this.timeout = 30000; // 默认30秒
        this.followRedirects = true;
    }

    // Getter方法
    public String getMethod() { return method; }
    public String getUrl() { return url; }
    public Map<String, String> getHeaders() { return new HashMap<>(headers); }
    public String getBody() { return body; }
    public int getTimeout() { return timeout; }
    public boolean isFollowRedirects() { return followRedirects; }

    @Override
    public String toString() {
        return "HttpRequest{" +
                "method='" + method + '\'' +
                ", url='" + url + '\'' +
                ", headers=" + headers +
                ", body='" + body + '\'' +
                ", timeout=" + timeout +
                ", followRedirects=" + followRedirects +
                '}';
    }

    // Builder类
    public static class Builder {
        private HttpRequest request;

        public Builder() {
            request = new HttpRequest();
        }

        public Builder method(String method) {
            request.method = method.toUpperCase();
            return this;
        }

        public Builder url(String url) {
            request.url = url;
            return this;
        }

        public Builder header(String key, String value) {
            request.headers.put(key, value);
            return this;
        }

        public Builder body(String body) {
            request.body = body;
            return this;
        }

        public Builder timeout(int timeout) {
            request.timeout = timeout;
            return this;
        }

        public Builder followRedirects(boolean followRedirects) {
            request.followRedirects = followRedirects;
            return this;
        }

        public HttpRequest build() {
            // 验证必要参数
            if (request.method == null) {
                throw new IllegalArgumentException("HTTP方法不能为空");
            }
            if (request.url == null) {
                throw new IllegalArgumentException("URL不能为空");
            }

            // 设置默认Content-Type
            if (request.body != null && !request.headers.containsKey("Content-Type")) {
                request.headers.put("Content-Type", "application/json");
            }

            return request;
        }
    }
}

// 使用示例
public class HttpRequestBuilderExample {
    public static void main(String[] args) {
        // 创建GET请求
        HttpRequest getRequest = new HttpRequest.Builder()
                .method("GET")
                .url("https://api.example.com/users")
                .header("Authorization", "Bearer token123")
                .header("Accept", "application/json")
                .timeout(5000)
                .build();

        System.out.println("GET请求: " + getRequest);

        // 创建POST请求
        HttpRequest postRequest = new HttpRequest.Builder()
                .method("POST")
                .url("https://api.example.com/users")
                .header("Authorization", "Bearer token123")
                .header("Accept", "application/json")
                .body("{\"name\":\"张三\",\"age\":25}")
                .timeout(10000)
                .followRedirects(false)
                .build();

        System.out.println("POST请求: " + postRequest);
    }
}

优缺点

优点

  • ✅ 可以精确控制对象的创建过程
  • ✅ 代码更易读和维护
  • ✅ 可以创建不可变对象
  • ✅ 支持链式调用
  • ✅ 参数验证更容易

缺点

  • ❌ 代码量增加
  • ❌ 对于简单对象可能过度设计
  • ❌ 需要创建多个类

总结

建造者模式的核心思想是:

  1. 分离关注点:将对象的创建和表示分离
  2. 分步构建:可以逐步设置对象的属性
  3. 链式调用:提供流畅的 API
  4. 参数验证:在构建过程中进行验证
  5. 不可变性:创建不可变对象

这种模式特别适合创建复杂对象,让代码更加清晰和易于维护。就像搭积木一样,你可以一步一步地构建出你想要的对象!

最近更新:: 2025/12/29 11:07
Contributors: Duke
Prev
适配器模式
Next
原型模式