1.定义
建造者模式(Builder Pattern)是一种创建型设计模式,它允许你分步骤创建复杂对象,而不必直接调用构造函数。建造者模式特别适合那些包含多个组成部分并且构造过程复杂的对象。
2. 结构
建造者模式的主要组成部分包括:
- 产品(Product): 要创建的复杂对象。
- 建造者(Builder): 用于创建产品各个部分的抽象接口。
- 具体建造者(Concrete Builder): 实现Builder接口,构造和装配产品的各个部分。
- 指挥者(Director): 负责管理建造过程,指导建造者如何构建产品。
3. 类图
4. 实现步骤
- 定义产品类: 这类是要创建的复杂对象,包含多个部分。
- 定义抽象建造者接口: 定义构建产品各部分的方法。
- 实现具体建造者类: 实现接口,完成各部分的构建。
- 定义指挥者类: 管理建造过程,使用建造者接口来创建产品。
5. 代码示例
// 产品类
class Computer {
private String cpu;
private String gpu;
private int ram;
private int storage;
public void setCpu(String cpu) {
this.cpu = cpu;
}
public void setGpu(String gpu) {
this.gpu = gpu;
}
public void setRam(int ram) {
this.ram = ram;
}
public void setStorage(int storage) {
this.storage = storage;
}
}
// 抽象建造者
interface ComputerBuilder {
void buildCPU();
void buildGPU();
void buildRAM();
void buildStorage();
Computer getResult();
}
// 具体建造者
class GamingComputerBuilder implements ComputerBuilder {
private Computer computer;
public GamingComputerBuilder() {
computer = new Computer();
}
@Override
public void buildCPU() {
computer.setCpu("Intel i9");
}
@Override
public void buildGPU() {
computer.setGpu("NVIDIA RTX 3080");
}
@Override
public void buildRAM() {
computer.setRam(32);
}
@Override
public void buildStorage() {
computer.setStorage(2000);
}
@Override
public Computer getResult() {
return computer;
}
}
// 指挥者
class Director {
private ComputerBuilder builder;
public Director(ComputerBuilder builder) {
this.builder = builder;
}
public Computer construct() {
builder.buildCPU();
builder.buildGPU();
builder.buildRAM();
builder.buildStorage();
return builder.getResult();
}
}
// 客户端代码示例
public class Client {
public static void main(String[] args) {
// 创建具体建造者
ComputerBuilder builder = new GamingComputerBuilder();
// 创建指挥者并传入建造者
Director director = new Director(builder);
// 构建复杂对象
Computer computer = director.construct();
}
}
在上述示例中:
Computer
是要构建的复杂对象,包含了几个部件(CPU、GPU、RAM、存储)。ComputerBuilder
是抽象建造者接口,定义了构建每个部件的方法。GamingComputerBuilder
是具体建造者,实现了具体部件的构建方法。Director
是指挥者,负责按照一定顺序调用具体建造者的方法来构建对象。Client
是客户端代码,通过指挥者来构建复杂对象。
6. 建造者模式的变体
内部类建造者
在实际开发中,使用内部类建造者最为常见,大多数第三方库和安卓系统源码也都使用了建造者模式,主要是方便好用。
public class Car {
private final String engine;
private final String body;
private final String wheels;
private final String interior;
private Car(Builder builder) {
this.engine = builder.engine;
this.body = builder.body;
this.wheels = builder.wheels;
this.interior = builder.interior;
}
public static class Builder {
private String engine;
private String body;
private String wheels;
private String interior;
public Builder setEngine(String engine) {
this.engine = engine;
return this;
}
public Builder setBody(String body) {
this.body = body;
return this;
}
public Builder setWheels(String wheels) {
this.wheels = wheels;
return this;
}
public Builder setInterior(String interior) {
this.interior = interior;
return this;
}
public Car build() {
return new Car(this);
}
}
@Override
public String toString() {
return "Car [Engine=" + engine + ", Body=" + body + ", Wheels=" + wheels + ", Interior=" + interior + "]";
}
public static void main(String[] args) {
Car car = new Car.Builder()
.setEngine("V8 Engine")
.setBody("SUV Body")
.setWheels("Alloy Wheels")
.setInterior("Leather Interior")
.build();
System.out.println(car);
}
}
7. 建造者模式经典应用 AlertDialog.Builder 源码分析
在 Android 源码中,AlertDialog.Builder
类用于创建 AlertDialog
对象。它提供了一种链式调用的方式来设置对话框的各种属性,如标题、消息、按钮等。
核心成员变量
private final AlertController.AlertParams P;
P
是 AlertController.AlertParams
的一个实例,用于存储和管理对话框的各种参数。
构造函数
public Builder(Context context) {
P = new AlertController.AlertParams(new ContextThemeWrapper(context,
resolveDialogTheme(context, 0 /* default theme */)));
}
在构造函数中,会创建一个 AlertController.AlertParams 对象,这个对象包含了对话框的参数设置。
设置标题和消息
public Builder setTitle(CharSequence title) {
P.mTitle = title;
return this;
}
public Builder setMessage(CharSequence message) {
P.mMessage = message;
return this;
}
设置按钮
public Builder setPositiveButton(CharSequence text, final OnClickListener listener) {
P.mPositiveButtonText = text;
P.mPositiveButtonListener = listener;
return this;
}
public Builder setNegativeButton(CharSequence text, final OnClickListener listener) {
P.mNegativeButtonText = text;
P.mNegativeButtonListener = listener;
return this;
}
这里的方法它们返回 Builder 对象自身,以支持链式调用。我们在自定义FragmentDialog的时候会经常用到。
创建对话框
public AlertDialog create() {
// Context has already been wrapped with the appropriate theme.
final AlertDialog dialog = new AlertDialog(P.mContext, 0, false);
P.apply(dialog.mAlert);
dialog.setCancelable(P.mCancelable);
if (P.mCancelable) {
dialog.setCanceledOnTouchOutside(true);
}
dialog.setOnCancelListener(P.mOnCancelListener);
dialog.setOnDismissListener(P.mOnDismissListener);
if (P.mOnKeyListener != null) {
dialog.setOnKeyListener(P.mOnKeyListener);
}
return dialog;
}
create()
方法用于实际创建 AlertDialog
对象。在这里,会通过 AlertController.apply()
方法将 AlertParams
中的参数应用到 AlertDialog
中,并设置对话框的可取消性、监听器等。
使用示例
不是吧啊sir ,AlertDialog
谁没用过啊,谁还看你的示例 。
好! 不写了 😊
8. 适用场景及优势
场景:
- 构建和表示分离: 产品的构建过程和最终表示需要解耦。
- 需要构建复杂对象: 产品包含多个部分,构建过程比较复杂。
- 需要多个产品表示: 同样的构建过程可以创建不同的产品表示。
优势:
- 灵活的对象构建: 可以根据需要调整构建过程,创建不同的产品表示。
- 高度可读的代码: 通过分步骤构建对象,使代码更易于理解和维护。
- 良好的扩展性: 可以轻松添加新的构建步骤或修改现有步骤,而不会影响客户端代码。
9. 结论
建造者模式是一种强大的设计模式,特别适合构建过程复杂的对象。它通过将对象的构建过程与表示分离,使得代码更具可读性和可维护性。同时,建造者模式还可以灵活地创建不同的产品表示。
建造者模式不难理解,记住好的代码都是重构出来的,设计模式也是,多写,多练才能真正掌握它的核心。