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

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;

P 是 AlertController.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. 结论


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

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

相关推荐
aibo8603081 分钟前
基于 Spring Boot + Vue3 的菜谱分享网站设计与实现
java·spring boot·后端
凤山老林3 分钟前
Spring Boot 集成 TOTP 双因素认证与恢复码机制
java·spring boot·后端
小冯不疯5 分钟前
物料主数据同步实战:从金蝶云星空到小满OKKICRM的单一策略深度拆解
java·大数据·数据库
vipxieliang9 分钟前
Spring Boot 测试策略:单元测试、切片测试与集成测试
java·spring boot·后端
估值探索者21 分钟前
【Python量化技术指标实战 04】布林带通道突破,怎么知道是真突破还是假突破?
java·开发语言·python·接口·股票数据api接口
未秃头的程序猿21 分钟前
同一个商户号,V2 免密代扣和 V3 分账的证书怎么共存?
java·后端·微信
captain37635 分钟前
Spring Boot的配置文件
java·spring boot·后端
captain37637 分钟前
Spring Boot日志
java·数据库·spring boot
Rabitebla1 小时前
【Linux】 权限篇(三):深入理解 umask 位运算与粘滞位的设计思想
java·linux·服务器·c++·笔记·学习
Pin_Qing1 小时前
缓存能活多久,现在是个要算的参数
java·大数据·开发语言·人工智能·程序人生