模式定义

建造者模式是一种创建型设计模式,它能将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。建造者模式关注如何分步创建复杂对象。

适用场景

结构图

graph TD A[Director] --> B{construct} B --> C[Builder] C --> D{buildPartA} C --> E{buildPartB} C --> F{buildPartC} G[ConcreteBuilder] --> H{buildPartA} G --> I{buildPartB} G --> J{buildPartC} G --> K[Product]

实现示例

Java 实现

// 产品类
public class Product {
    private String partA;
    private String partB;
    private String partC;
    
    public void setPartA(String partA) {
        this.partA = partA;
    }
    
    public void setPartB(String partB) {
        this.partB = partB;
    }
    
    public void setPartC(String partC) {
        this.partC = partC;
    }
    
    public void show() {
        System.out.println("Product Parts: " + partA + ", " + partB + ", " + partC);
    }
}

// 抽象建造者
public abstract class Builder {
    protected Product product = new Product();
    
    public abstract void buildPartA();
    public abstract void buildPartB();
    public abstract void buildPartC();
    
    public Product getResult() {
        return product;
    }
}

// 具体建造者
public class ConcreteBuilder extends Builder {
    @Override
    public void buildPartA() {
        product.setPartA("建造 PartA");
    }
    
    @Override
    public void buildPartB() {
        product.setPartB("建造 PartB");
    }
    
    @Override
    public void buildPartC() {
        product.setPartC("建造 PartC");
    }
}

// 指挥者
public class Director {
    private Builder builder;
    
    public Director(Builder builder) {
        this.builder = builder;
    }
    
    public Product construct() {
        builder.buildPartA();
        builder.buildPartB();
        builder.buildPartC();
        return builder.getResult();
    }
}
                

经典案例

1. StringBuilder类

Java标准库中的StringBuilder就是建造者模式的应用:

// StringBuilder是建造者模式的典型应用
public class StringBuilderExample {
    public static void main(String[] args) {
        // 使用StringBuilder逐步构建字符串
        StringBuilder builder = new StringBuilder();
        builder.append("Hello");
        builder.append(" ");
        builder.append("World");
        builder.append("!");
        
        // 最终获取结果
        String result = builder.toString();
        System.out.println(result); // 输出: Hello World!
        
        // StringBuilder内部逐步构建字符串对象
        // 每次append操作都是在构建最终的字符串表示
    }
}

// StringBuilder的简化实现示例
public class SimpleStringBuilder {
    private char[] value;
    private int count;
    
    public SimpleStringBuilder() {
        this(16);
    }
    
    public SimpleStringBuilder(int capacity) {
        value = new char[capacity];
    }
    
    // 建造者方法 - 逐步构建字符串
    public SimpleStringBuilder append(String str) {
        if (str == null) str = "null";
        int len = str.length();
        ensureCapacity(count + len);
        str.getChars(0, len, value, count);
        count += len;
        return this;
    }
    
    // 建造者方法
    public SimpleStringBuilder append(int i) {
        return append(String.valueOf(i));
    }
    
    // 建造者方法
    public SimpleStringBuilder append(char c) {
        ensureCapacity(count + 1);
        value[count++] = c;
        return this;
    }
    
    // 获取最终构建的产品
    public String toString() {
        return new String(value, 0, count);
    }
    
    private void ensureCapacity(int minimumCapacity) {
        if (minimumCapacity - value.length > 0) {
            expandCapacity(minimumCapacity);
        }
    }
    
    private void expandCapacity(int minimumCapacity) {
        int newCapacity = value.length * 2 + 2;
        if (newCapacity - minimumCapacity < 0)
            newCapacity = minimumCapacity;
        value = Arrays.copyOf(value, newCapacity);
    }
}

2. Spring框架中的BeanDefinitionBuilder

Spring框架中使用建造者模式来构建Bean定义:

// Spring中的BeanDefinitionBuilder使用了建造者模式
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.RootBeanDefinition;

public class SpringBeanBuilderExample {
    public static void main(String[] args) {
        // 使用BeanDefinitionBuilder逐步构建Bean定义
        BeanDefinitionBuilder builder = BeanDefinitionBuilder
            .rootBeanDefinition(MyService.class)
            .addPropertyValue("name", "testService")
            .addPropertyValue("timeout", 5000)
            .setScope("prototype")
            .setLazyInit(false);
        
        // 获取最终的Bean定义
        RootBeanDefinition beanDefinition = 
            (RootBeanDefinition) builder.getBeanDefinition();
        
        // 注册到Bean工厂
        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
        factory.registerBeanDefinition("myService", beanDefinition);
    }
}

// 自定义服务类
class MyService {
    private String name;
    private int timeout;
    
    // getter和setter方法
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public int getTimeout() { return timeout; }
    public void setTimeout(int timeout) { this.timeout = timeout; }
}

3. HTTP请求构建

在实际项目中,建造者模式常用于构建复杂的HTTP请求:

// HTTP请求建造者模式实现
public class HttpRequest {
    private String url;
    private String method;
    private Map headers;
    private String body;
    private int timeout;
    
    private HttpRequest(Builder builder) {
        this.url = builder.url;
        this.method = builder.method;
        this.headers = builder.headers;
        this.body = builder.body;
        this.timeout = builder.timeout;
    }
    
    // getter方法
    public String getUrl() { return url; }
    public String getMethod() { return method; }
    public Map getHeaders() { return headers; }
    public String getBody() { return body; }
    public int getTimeout() { return timeout; }
    
    // 静态内部建造者类
    public static class Builder {
        private String url;
        private String method = "GET";
        private Map headers = new HashMap<>();
        private String body;
        private int timeout = 5000;
        
        public Builder(String url) {
            this.url = url;
        }
        
        public Builder method(String method) {
            this.method = method;
            return this;
        }
        
        public Builder addHeader(String key, String value) {
            this.headers.put(key, value);
            return this;
        }
        
        public Builder body(String body) {
            this.body = body;
            return this;
        }
        
        public Builder timeout(int timeout) {
            this.timeout = timeout;
            return this;
        }
        
        public HttpRequest build() {
            // 可以在这里添加验证逻辑
            if (url == null || url.isEmpty()) {
                throw new IllegalArgumentException("URL不能为空");
            }
            return new HttpRequest(this);
        }
    }
    
    @Override
    public String toString() {
        return "HttpRequest{" +
                "url='" + url + '\'' +
                ", method='" + method + '\'' +
                ", headers=" + headers +
                ", body='" + body + '\'' +
                ", timeout=" + timeout +
                '}';
    }
}

// 使用示例
public class HttpRequestBuilderExample {
    public static void main(String[] args) {
        // 使用建造者模式构建HTTP请求
        HttpRequest request = new HttpRequest.Builder("https://api.example.com/users")
                .method("POST")
                .addHeader("Content-Type", "application/json")
                .addHeader("Authorization", "Bearer token123")
                .body("{\"name\":\"张三\", \"age\":30}")
                .timeout(10000)
                .build();
        
        System.out.println(request);
        
        // 发送请求的逻辑...
        // sendRequest(request);
    }
    
    // 模拟发送请求的方法
    private static void sendRequest(HttpRequest request) {
        System.out.println("发送请求到: " + request.getUrl());
        System.out.println("方法: " + request.getMethod());
        System.out.println("头部: " + request.getHeaders());
        System.out.println("内容: " + request.getBody());
        System.out.println("超时: " + request.getTimeout() + "ms");
    }
}

优缺点

优点

  • 建造者独立,易扩展
  • 便于控制细节风险
  • 产品的创建过程可以被精确控制

缺点

  • 产品必须有共同点,范围有限制
  • 如内部变化复杂,会有很多的建造类