04.建造者模式的终极手册:从快餐定制到航天飞船的组装哲学

发布于:2025-07-25 ⋅ 阅读:(40) ⋅ 点赞:(0)

序章:当你的对象比巨无霸汉堡更复杂时

🍔 订餐困境
你想点一份包含三层牛肉、双份芝士、不要酸黄瓜、加辣蛋黄酱、搭配番薯条的定制汉堡——普通构造器需要8个参数且充满null值!建造者模式就是你的"订单配置系统",让你用优雅的方式组装复杂对象。


一、基础建造师入门课

1.1 传统Builder模式实现

// 宇宙飞船的零件清单
public class SpaceShip {
    private final String engine;      // 必选
    private final int fuel;           // 必选
    private String weaponSystem;      // 可选
    private boolean escapePod;         // 可选
    private String aiCore;            // 可选

    private SpaceShip(Builder builder) {
        this.engine = builder.engine;
        this.fuel = builder.fuel;
        this.weaponSystem = builder.weaponSystem;
        this.escapePod = builder.escapePod;
        this.aiCore = builder.aiCore;
    }

    // 建造者控制台
    public static class Builder {
        private final String engine;
        private final int fuel;
        private String weaponSystem = "None";
        private boolean escapePod;
        private String aiCore = "Basic";

        public Builder(String engine, int fuel) {
            this.engine = engine;
            this.fuel = fuel;
        }

        public Builder weaponSystem(String system) {
            this.weaponSystem = system;
            return this;
        }

        public Builder escapePod(boolean hasPod) {
            this.escapePod = hasPod;
            return this;
        }

        public Builder aiCore(String core) {
            this.aiCore = core;
            return this;
        }

        public SpaceShip build() {
            validate();
            return new SpaceShip(this);
        }

        private void validate() {
            if (fuel < 1000) {
                throw new IllegalArgumentException("燃料不足最低阈值!");
            }
        }
    }
}

// 使用示例:组装歼星舰
SpaceShip deathStar = new SpaceShip.Builder("超物质引擎", 5000)
                                .weaponSystem("超级激光炮")
                                .escapePod(true)
                                .aiCore("天网")
                                .build();

模式优势

  • 强制必选参数校验
  • 可选参数灵活组合
  • 构建过程线程安全
  • 参数顺序无关性

二、现代建造师进化指南

2.1 流式接口(Fluent API)

// 咖啡订单构建器
public class Coffee {
    private String size;
    private boolean milk;
    private int sugar;
    private String extra;

    public static class Builder {
        private Coffee coffee = new Coffee();

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

        public Builder milk(boolean milk) {
            coffee.milk = milk;
            return this;
        }

        public Builder sugar(int cubes) {
            coffee.sugar = cubes;
            return this;
        }

        public Builder extra(String item) {
            coffee.extra = item;
            return this;
        }

        public Coffee brew() {
            if (coffee.size == null) {
                throw new IllegalStateException("必须选择杯型!");
            }
            return coffee;
        }
    }
}

// 使用链式调用
Coffee myCoffee = new Coffee.Builder()
                          .size("大杯")
                          .milk(true)
                          .sugar(2)
                          .extra("焦糖")
                          .brew();

2.2 Lombok建造者(极简主义)

@Builder
@ToString
public class SmartPhone {
    @NonNull
    private String model;
    @Builder.Default
    private int ram = 8;     // 默认值
    @Builder.Default
    private int storage = 128;
    private boolean nfc;
    private String color;
}

// 自动生成建造者
SmartPhone phone = SmartPhone.builder()
                           .model("XPhone 15")
                           .ram(12)
                           .color("星际黑")
                           .build();

三、高级建造工厂

3.1 泛型建造者

// 通用建造者接口
public interface Builder<T> {
    T build();
}

// 房屋建造实现
public class HouseBuilder implements Builder<House> {
    private House house = new House();

    public HouseBuilder addRooms(int rooms) {
        house.setRooms(rooms);
        return this;
    }

    public HouseBuilder addPool() {
        house.setHasPool(true);
        return this;
    }

    @Override
    public House build() {
        return house;
    }
}

// 导演类控制建造流程
public class Architect {
    public House buildMansion(Builder<House> builder) {
        return ((HouseBuilder) builder)
                 .addRooms(10)
                 .addPool()
                 .build();
    }
}

3.2 线程安全建造者

public class ThreadSafePCBuilder {
    private volatile String cpu;
    private volatile String gpu;
    private volatile int ram;

    public synchronized ThreadSafePCBuilder setCpu(String cpu) {
        this.cpu = cpu;
        return this;
    }

    public synchronized ThreadSafePCBuilder setGpu(String gpu) {
        this.gpu = gpu;
        return this;
    }

    public synchronized ThreadSafePCBuilder setRam(int ram) {
        this.ram = ram;
        return this;
    }

    public PC build() {
        return new PC(cpu, gpu, ram);
    }
}

四、特殊建造技巧

4.1 组合建造者

// 组合汽车部件
public class CarBuilder {
    private EngineBuilder engineBuilder = new EngineBuilder();
    private WheelBuilder wheelBuilder = new WheelBuilder();

    public CarBuilder withV8Engine() {
        engineBuilder.setType("V8");
        return this;
    }

    public CarBuilder withSportWheels() {
        wheelBuilder.setType("Sport");
        return this;
    }

    public Car build() {
        return new Car(engineBuilder.build(), wheelBuilder.build());
    }
}

// 创建跑车
Car sportsCar = new CarBuilder()
                .withV8Engine()
                .withSportWheels()
                .build();

4.2 分阶段建造

// 分阶段接口
public interface Stage1 {
    Stage2 setCPU(String cpu);
}

public interface Stage2 {
    Stage3 setGPU(String gpu);
}

public interface Stage3 {
    PCBuilder setRAM(int ram);
}

public class PCBuilder implements Stage1, Stage2, Stage3 {
    // 强制按顺序配置
    @Override
    public Stage2 setCPU(String cpu) { /*...*/ }

    @Override
    public Stage3 setGPU(String gpu) { /*...*/ }

    @Override
    public PC build() { /*...*/ }
}

// 确保正确配置顺序
PC gamingPC = new PCBuilder()
                .setCPU("i9")
                .setGPU("RTX 4090")
                .setRAM(64)
                .build();

五、Spring中的建造者模式

5.1 结合工厂模式

@Configuration
public class Config {
    @Bean
    @Scope("prototype")
    public PizzaBuilder pizzaBuilder() {
        return new PizzaBuilder();
    }
}

@Service
public class PizzaService {
    private final PizzaBuilder builder;

    public PizzaService(PizzaBuilder builder) {
        this.builder = builder;
    }

    public Pizza createSpecialPizza() {
        return builder.size("XL")
                    .crust("芝士卷边")
                    .topping("双份芝士")
                    .build();
    }
}

5.2 配置类建造者

@ConfigurationProperties(prefix = "mail")
public class MailConfig {
    private String host;
    private int port;
    // Builder生成配置对象
    public static MailConfigBuilder builder() {
        return new MailConfigBuilder();
    }
}

// application.yml配置
mail:
  host: smtp.example.com
  port: 587

建造者模式选择指南

实现方式 适用场景 优点 缺点
传统Builder 需要严格校验的复杂对象 线程安全,强校验 代码量大
流式接口 可选参数多的配置类 调用直观,易扩展 无法强制必选参数
Lombok Builder 快速开发简单DTO 代码极简 灵活性受限
泛型建造者 需要统一构建接口的系统 提高代码复用率 类型转换需要处理
分阶段建造 必须按步骤配置的对象 保证配置顺序 使用复杂度稍高

终章:建造者的宇宙法则

当你面对以下场景时,请召唤建造者模式:

  1. 对象包含多个可选参数(超过4个参数)
  2. 需要不同组合的构造方式
  3. 要求对象不可变(Immutable)
  4. 需要分步构造复杂对象

禁忌时刻

  • 当对象非常简单(3个以下参数)时
  • 当构造过程不需要灵活性时
  • 当性能要求极高(纳秒级)的场景

最后,记住一位资深架构师的名言:“建造者模式不是为了炫技,而是为了在复杂性与可维护性之间找到完美平衡。”

创作挑战
如果要实现一个支持撤销操作的建造者(比如用户可以回退到上一步配置),如何设计这样的建造者结构?把你的设计草图留在评论区吧!🚀👩💻


网站公告

今日签到

点亮在社区的每一天
去签到