设计模式——建造者模式

建造者模式 (Builder Pattern)

什么是建造者模式?

建造者模式是一种创建型设计模式,它允许你分步骤创建复杂对象。该模式能让你使用相同的创建过程生成不同类型和形式的对象。

简单来说:建造者模式就是将复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。

生活中的例子

想象一家快餐店

  • 汉堡:可以有或没有芝士、番茄、生菜、洋葱等
  • 点餐过程
    1. 选择面包
    2. 选择肉饼
    3. 选择配料(芝士、番茄、生菜、洋葱等)
    4. 选择酱料

建造者模式可以让你:

  • 灵活地选择不同的配料组合
  • 创建不同类型的汉堡(芝士汉堡、蔬菜汉堡、双层汉堡等)
  • 使用相同的构建过程

为什么需要建造者模式?

传统方式的问题

java 复制代码
// 使用构造函数创建对象
Computer computer = new Computer("Intel i7", "16GB", "512GB SSD", 
                                  "Windows 10", "NVIDIA RTX 3080", 
                                  "27英寸显示器", "机械键盘", "无线鼠标");

问题

  1. 参数过多:构造函数参数列表过长,难以记忆和使用
  2. 参数顺序依赖:必须按特定顺序传递参数
  3. 可选参数处理困难:某些参数可选时,需要多个构造函数
  4. 可读性差:无法从代码中看出每个参数的含义

建造者模式的优势

java 复制代码
Computer computer = new Computer.Builder()
    .cpu("Intel i7")
    .ram("16GB")
    .storage("512GB SSD")
    .gpu("NVIDIA RTX 3080")
    .build();

优势

  1. 参数清晰:每个参数都有明确的名称
  2. 参数顺序无关:可以按任意顺序设置参数
  3. 可选参数灵活:可选参数可以不设置
  4. 可读性好:代码清晰易懂
  5. 不可变对象:可以创建不可变对象

建造者模式的结构

复制代码
┌─────────────────────┐
│      Product        │  产品
├─────────────────────┤
│ - part1: String     │
│ - part2: String     │
│ - part3: String     │
└─────────────────────┘

┌─────────────────────┐
│      Builder        │  抽象建造者
├─────────────────────┤
│ + build(): Product  │
│ + setPart1(): void  │
│ + setPart2(): void  │
│ + setPart3(): void  │
└──────────┬──────────┘
           │ 继承
           │
┌──────────┴──────────┐
│  ConcreteBuilder    │  具体建造者
├─────────────────────┤
│ - product: Product  │
│ + build(): Product  │
│ + setPart1(): void  │
│ + setPart2(): void  │
│ + setPart3(): void  │
└─────────────────────┘

┌─────────────────────┐
│      Director       │  指挥者(可选)
├─────────────────────┤
│ - builder: Builder  │
│ + construct(): void │
└─────────────────────┘

代码示例

1. 定义产品

java 复制代码
/**
 * 产品:电脑
 */
public class Computer {
    private String cpu;
    private String ram;
    private String storage;
    private String gpu;
    private String os;
    private String monitor;
    private String keyboard;
    private String mouse;
    
    // 私有构造函数,只能通过Builder创建
    private Computer(Builder builder) {
        this.cpu = builder.cpu;
        this.ram = builder.ram;
        this.storage = builder.storage;
        this.gpu = builder.gpu;
        this.os = builder.os;
        this.monitor = builder.monitor;
        this.keyboard = builder.keyboard;
        this.mouse = builder.mouse;
    }
    
    /**
     * 显示电脑配置
     */
    public void display() {
        System.out.println("电脑配置:");
        System.out.println("  CPU: " + cpu);
        System.out.println("  内存: " + ram);
        System.out.println("  存储: " + storage);
        if (gpu != null) System.out.println("  显卡: " + gpu);
        if (os != null) System.out.println("  操作系统: " + os);
        if (monitor != null) System.out.println("  显示器: " + monitor);
        if (keyboard != null) System.out.println("  键盘: " + keyboard);
        if (mouse != null) System.out.println("  鼠标: " + mouse);
    }
    
    /**
     * Builder类
     */
    public static class Builder {
        // 必需参数
        private String cpu;
        private String ram;
        private String storage;
        
        // 可选参数
        private String gpu;
        private String os;
        private String monitor;
        private String keyboard;
        private String mouse;
        
        public Builder(String cpu, String ram, String storage) {
            this.cpu = cpu;
            this.ram = ram;
            this.storage = storage;
        }
        
        public Builder gpu(String gpu) {
            this.gpu = gpu;
            return this;
        }
        
        public Builder os(String os) {
            this.os = os;
            return this;
        }
        
        public Builder monitor(String monitor) {
            this.monitor = monitor;
            return this;
        }
        
        public Builder keyboard(String keyboard) {
            this.keyboard = keyboard;
            return this;
        }
        
        public Builder mouse(String mouse) {
            this.mouse = mouse;
            return this;
        }
        
        public Computer build() {
            return new Computer(this);
        }
    }
}

2. 使用Builder

java 复制代码
/**
 * 建造者模式测试类
 * 演示如何使用建造者模式创建不同配置的电脑
 */
public class BuilderTest {
    
    public static void main(String[] args) {
        System.out.println("=== 建造者模式测试 ===\n");
        
        // 创建基础配置的办公电脑
        System.out.println("--- 办公电脑 ---");
        Computer officePC = new Computer.Builder(
            "Intel i5",
            "8GB",
            "256GB SSD"
        ).os("Windows 10")
         .build();
        officePC.display();
        
        System.out.println();
        
        // 创建游戏电脑
        System.out.println("--- 游戏电脑 ---");
        Computer gamingPC = new Computer.Builder(
            "Intel i9",
            "32GB",
            "1TB SSD"
        ).gpu("NVIDIA RTX 4090")
         .os("Windows 11")
         .monitor("27英寸 144Hz显示器")
         .keyboard("机械键盘")
         .mouse("游戏鼠标")
         .build();
        gamingPC.display();
        
        System.out.println();
        
        // 创建开发电脑
        System.out.println("--- 开发电脑 ---");
        Computer devPC = new Computer.Builder(
            "AMD Ryzen 9",
            "64GB",
            "2TB NVMe SSD"
        ).gpu("NVIDIA RTX 3080")
         .os("Ubuntu 22.04")
         .monitor("双显示器")
         .keyboard("HHKB键盘")
         .mouse("垂直鼠标")
         .build();
        devPC.display();
        
        System.out.println("\n=== 建造者模式的优势 ===");
        System.out.println("1. 参数清晰:每个参数都有明确的名称");
        System.out.println("2. 参数顺序无关:可以按任意顺序设置参数");
        System.out.println("3. 可选参数灵活:可选参数可以不设置");
        System.out.println("4. 代码可读性好:代码清晰易懂");
        System.out.println("5. 不可变对象:可以创建不可变对象");
    }
}

建造者模式的优点

  1. 分步骤创建:可以分步骤创建复杂对象
  2. 参数清晰:每个参数都有明确的名称
  3. 代码可读:代码清晰易懂
  4. 灵活扩展:可以轻松添加新的参数
  5. 不可变对象:可以创建不可变对象

建造者模式的缺点

  1. 代码量增加:需要创建Builder类
  2. 性能开销:创建对象需要额外的步骤

适用场景

  1. 复杂对象:需要创建复杂对象,且对象有多个组成部分
  2. 参数众多:构造函数参数过多
  3. 可选参数:有多个可选参数
  4. 不同表示:需要使用相同的创建过程创建不同的表示

常见应用场景

  • StringBuilder:Java中的StringBuilder
  • 文档构建:HTML、XML、JSON文档的构建
  • SQL查询构建:动态SQL查询的构建
  • 配置对象:配置对象的创建

使用建议

  • 参数超过4个:考虑使用建造者模式
  • 有可选参数:考虑使用建造者模式
  • 需要不可变对象:考虑使用建造者模式
  • 简单对象:直接使用构造函数即可

注意事项

⚠️ 建造者模式虽然很好,但不要滥用:

  • 如果对象很简单,直接使用构造函数或setter方法
  • 如果参数很少(<4个),不需要使用建造者模式
  • 建造者模式会增加代码量,要权衡利弊
相关推荐
9稳2 小时前
基于单片机的家庭安全系统设计
开发语言·网络·数据库·单片机·嵌入式硬件
一路往蓝-Anbo2 小时前
第37期:启动流程(二):C Runtime (CRT) 初始化与重定位
c语言·开发语言·网络·stm32·单片机·嵌入式硬件
longxiangam2 小时前
基于esp32p4 的掌机
单片机·嵌入式硬件
赤~峰3 小时前
S32DS for S32 Platform GPIO输入中断实践
单片机·嵌入式硬件
小码过河.4 小时前
设计模式——工厂方法模式
设计模式·工厂方法模式
把csdn当日记本的菜鸡4 小时前
Java设计模式简单入门
java·开发语言·设计模式
三伏5225 小时前
HAL_I2C_ER_IRQHandler函数解析
stm32·单片机·hal库
老蒋每日coding5 小时前
AI Agent 设计模式系列(十一)—— 目标设定和监控模式
人工智能·设计模式·langchain
蔺太微5 小时前
外观模式(Facade Pattern)
设计模式·外观模式