建造者(Builder)模式

177 阅读5分钟

点击阅读:设计模式系列文章

1. 建造者模式概述

1.1 建造者模式概述

建造者模式(Builder Pattern)是创建型设计模式,核心思想是将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

1. 复杂对象的构建

“复杂对象”指的是那些需要多个步骤来创建,或者其创建过程涉及到多个部分或组件的对象。构建过程可能包括设置对象的属性、初始化内部状态、组合其他对象等。

2. 与其表示分离

“表示”指的是对象的具体形式或类型。分离构建过程与表示意味着,构建过程本身并不依赖于特定类型的对象,而是可以应用于多种类型的对象。这通常通过定义一个抽象的构建过程(比如一个接口或抽象类),然后让具体的构建器实现这个构建过程来实现。

3. 使得同样的构建过程可以创建不同的表示

通过使用不同的具体构建器,相同的构建步骤可以生成不同类型的产品。这增加了代码的复用性和灵活性,因为你可以在不改变构建过程的情况下,通过简单地替换构建器来改变最终产品的类型。

建造者模式可以将一个产品的内部表象与产品的生成过程分割开来,从而可以使一个建造过程生成具有不同的内部表象的产品对象。如果我们用了建造者模式,那么用户就只指定需要建造的类型就可以得到它们,而具体建造的过程和细节就不需要知道了。

1.2 建造者模式优点

在面向对象设计中,建造者模式解决了"对象创建责任过载"的问题。传统构造器在面对多参数、可选参数场景时,会面临以下困境:

  1. 参数顺序耦合:调用者必须记住参数顺序
  2. 可读性灾难new Person("张", "三", 30, null, "北京", null, true)难以理解
  3. 参数组合爆炸:随着参数增加,构造器方法数量呈指数增长

建造者模式通过引入间接层(Builder类)解耦对象构建过程,实现了:

  1. 分步构建(Step-by-step construction)
  2. 参数可选性(Optional parameters)
  3. 构建过程抽象(Construction process abstraction)
graph LR
A[客户端] --> B[Builder]
B --> C[构建过程]
C --> D[最终产品]

2. 建造者模式使用场景

建造者模式使用场景:

  1. 多参数对象创建:4个以上参数,尤其含多个可选参数
  2. 复合对象创建:对象包含多个子对象(如订单含商品/支付/配送)
  3. 配置复杂对象:需要分步设置的组件(如 Android 的 AlertDialog)
  4. 不可变对象创建:final 字段需一次性初始化
  5. 对象创建过程需精细化控制:如添加参数校验、默认值等逻辑

3. 建造者模式举例

使用建造者模式构建汽车对象,定义汽车类:

public class Car {
    // 汽车的各个部件
    private final String make;    // 品牌
    private final String model;   // 型号
    private final int year;       // 年份
    private final String color;   // 颜色
    private final boolean hasSunroof; // 是否有天窗
    private final boolean hasNavigation; // 是否有导航
 
    // 私有
    private Car(CarBuilder builder) {
        this.make = builder.make;
        this.model = builder.model;
        this.year = builder.year;
        this.color = builder.color;
        this.hasSunroof = builder.hasSunroof;
        this.hasNavigation = builder.hasNavigation;
    }
 
    // 省略getter方法...
 
    // 静态内部类 Builder,用于构建Car对象
    public static class Builder {
        // 与Car类属性对应的字段
        private String make;
        private String model;
        private int year;
        private String color;
        private boolean hasSunroof;
        private boolean hasNavigation;
 
        // 构造函数,设置必填参数
        public CarBuilder(String make, String model) {
            this.make = make;
            this.model = model;
        }
 
        // 提供方法设置各个部件,返回Builder对象以便链式调用
        public CarBuilder setYear(int year) {
            this.year = year;
            return this;
        }
 
        public CarBuilder setColor(String color) {
            this.color = color;
            return this;
        }
 
        public CarBuilder setHasSunroof(boolean hasSunroof) {
            this.hasSunroof = hasSunroof;
            return this;
        }
 
        public CarBuilder setHasNavigation(boolean hasNavigation) {
            this.hasNavigation = hasNavigation;
            return this;
        }
 
        // 构建最终的对象
        public Car build() {
            return new Car(this);
        }
    }
}

客户端代码:

// 使用Builder构建Car对象
Car car = new Car.CarBuilder("Toyota", "Camry")
        .setYear(2023)
        .setColor("Red")
        .setHasSunroof(true)
        .setHasNavigation(false)
        .build();

Android Dialog 的创建:

// 建造者模式创建AlertDialog(系统原生实现)
AlertDialog dialog = new AlertDialog.Builder(this)
        .setTitle("系统提示")
        .setMessage("确定删除此文件?")
        .setIcon(R.drawable.ic_warning)
        .setPositiveButton("确定", (d, which) -> {
            // 处理确定操作
        })
        .setNegativeButton("取消", (d, which) -> {
            // 处理取消操作
        })
        .setCancelable(false)
        .create();

// 自定义Dialog建造者
public class CustomDialogBuilder {
    private Context context;
    private String title;
    private String message;
    // 其他参数...

    public CustomDialogBuilder(Context context) {
        this.context = context;
    }

    public CustomDialogBuilder setTitle(String title) {
        this.title = title;
        return this;
    }

    public CustomDialogBuilder setMessage(String message) {
        this.message = message;
        return this;
    }

    public Dialog build() {
        AlertDialog dialog = new AlertDialog.Builder(context)
            .setTitle(title)
            .setMessage(message)
            // 应用其他参数...
            .create();
        dialog.getWindow().setBackgroundDrawableResource(R.drawable.dialog_bg);
        return dialog;
    }
}

复杂自定义View的建造者模式实现:

public class CustomChartView extends View {
    private final String title;
    private final int[] dataPoints;
    private final int chartColor;
    private final boolean showLegend;
    
    private CustomChartView(ChartBuilder builder) {
        // 初始化操作
    }
    
    public static class ChartBuilder {
        private final Context context;
        private String title = "默认标题";
        private int[] dataPoints = new int[0];
        private int chartColor = Color.BLUE;
        private boolean showLegend = true;
        
        public ChartBuilder(Context context) {
            this.context = context;
        }
        
        public ChartBuilder setTitle(String title) {
            this.title = title;
            return this;
        }
        
        public ChartBuilder setDataPoints(int[] data) {
            this.dataPoints = data;
            return this;
        }
        
        public ChartBuilder setChartColor(@ColorInt int color) {
            this.chartColor = color;
            return this;
        }
        
        public ChartBuilder setShowLegend(boolean show) {
            this.showLegend = show;
            return this;
        }
        
        public CustomChartView build() {
            // 数据校验
            if (dataPoints.length == 0) {
                throw new IllegalArgumentException("必须提供数据点");
            }
            return new CustomChartView(this);
        }
    }
}

// 使用示例
CustomChartView chart = new CustomChartView.ChartBuilder(context)
        .setTitle("销售数据")
        .setDataPoints(new int[]{120, 135, 147, 160, 155})
        .setChartColor(ContextCompat.getColor(context, R.color.chart_color))
        .build();

4. 总结

建造者模式已演化为不可或缺的核心模式,其价值体现在:

  1. 复杂对象构建标准化:为多参数对象提供统一构建接口
  2. API设计友好性:提升SDK易用性和可读性
  3. 不可变对象支持:保障线程安全的核心机制
  4. 组合对象构建:管理嵌套对象创建的复杂性
  5. 配置与实现分离:符合开闭原则的设计典范