技术成神之路:设计模式(二)建造者模式

1.定义


建造者模式(Builder Pattern)是一种创建型设计模式,它允许你分步骤创建复杂对象,而不必直接调用构造函数。建造者模式特别适合那些包含多个组成部分并且构造过程复杂的对象。

2. 结构


建造者模式的主要组成部分包括:

  • 产品(Product): 要创建的复杂对象。
  • 建造者(Builder): 用于创建产品各个部分的抽象接口。
  • 具体建造者(Concrete Builder): 实现Builder接口,构造和装配产品的各个部分。
  • 指挥者(Director): 负责管理建造过程,指导建造者如何构建产品。

3. 类图


4. 实现步骤


  • 定义产品类: 这类是要创建的复杂对象,包含多个部分。
  • 定义抽象建造者接口: 定义构建产品各部分的方法。
  • 实现具体建造者类: 实现接口,完成各部分的构建。
  • 定义指挥者类: 管理建造过程,使用建造者接口来创建产品。

5. 代码示例


cpp 复制代码
// 产品类
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. 建造者模式的变体


内部类建造者

在实际开发中,使用内部类建造者最为常见,大多数第三方库和安卓系统源码也都使用了建造者模式,主要是方便好用。

java 复制代码
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 对象。它提供了一种链式调用的方式来设置对话框的各种属性,如标题、消息、按钮等。

核心成员变量

java 复制代码
private final AlertController.AlertParams P;

PAlertController.AlertParams 的一个实例,用于存储和管理对话框的各种参数。

构造函数

java 复制代码
public Builder(Context context) {
    P = new AlertController.AlertParams(new ContextThemeWrapper(context,
            resolveDialogTheme(context, 0 /* default theme */)));
}

在构造函数中,会创建一个 AlertController.AlertParams 对象,这个对象包含了对话框的参数设置。

设置标题和消息

java 复制代码
public Builder setTitle(CharSequence title) {
    P.mTitle = title;
    return this;
}

public Builder setMessage(CharSequence message) {
    P.mMessage = message;
    return this;
}

设置按钮

java 复制代码
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的时候会经常用到。

创建对话框

cpp 复制代码
 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. 结论


建造者模式是一种强大的设计模式,特别适合构建过程复杂的对象。它通过将对象的构建过程与表示分离,使得代码更具可读性和可维护性。同时,建造者模式还可以灵活地创建不同的产品表示。

建造者模式不难理解,记住好的代码都是重构出来的,设计模式也是,多写,多练才能真正掌握它的核心。

相关推荐
2202_75442154几秒前
生成MPSOC以及ZYNQ的启动文件BOOT.BIN的小软件
java·linux·开发语言
蓝染-惣右介3 分钟前
【MyBatisPlus·最新教程】包含多个改造案例,常用注解、条件构造器、代码生成、静态工具、类型处理器、分页插件、自动填充字段
java·数据库·tomcat·mybatis
小林想被监督学习4 分钟前
idea怎么打开两个窗口,运行两个项目
java·ide·intellij-idea
HoneyMoose6 分钟前
IDEA 2024.3 版本更新主要功能介绍
java·ide·intellij-idea
我只会发热7 分钟前
Java SE 与 Java EE:基础与进阶的探索之旅
java·开发语言·java-ee
是老余9 分钟前
本地可运行,jar包运行错误【解决实例】:通过IDEA的maven package打包多模块项目
java·maven·intellij-idea·jar
crazy_wsp9 分钟前
IDEA怎么定位java类所用maven依赖版本及引用位置
java·maven·intellij-idea
.Ayang11 分钟前
tomcat 后台部署 war 包 getshell
java·计算机网络·安全·web安全·网络安全·tomcat·网络攻击模型
一直学习永不止步17 分钟前
LeetCode题练习与总结:最长回文串--409
java·数据结构·算法·leetcode·字符串·贪心·哈希表
博风26 分钟前
设计模式:6、装饰模式(包装器)
设计模式