Java编程之建造者模式

news2025/6/6 9:55:56

建造者模式(Builder Pattern)是一种创建型设计模式,它将一个复杂对象的构建与表示分离,使得同样的构建过程可以创建不同的表示。这种模式允许你分步骤构建一个复杂对象,并且可以在构建过程中进行不同的配置。

模式的核心组件

建造者模式通常包含以下四个核心组件:

  1. 产品(Product):要构建的复杂对象。
  2. 抽象建造者(Builder):定义了构建产品各个部分的抽象接口。
  3. 具体建造者(Concrete Builder):实现抽象建造者接口,完成产品各部分的具体构建。
  4. 指挥者(Director):负责安排复杂对象的构建顺序,并使用建造者对象构建产品。

简单实现

让我们通过一个示例来详细说明建造者模式的实现。假设我们要构建一个电脑(Computer)对象,它包含 CPU、内存、硬盘和显卡等组件。

首先,定义产品类:

// 产品类:电脑
public class Computer {
    private String cpu;
    private String memory;
    private String hardDisk;
    private String graphicsCard;

    // 私有构造函数,只能通过Builder创建Computer
    private Computer(Builder builder) {
        this.cpu = builder.cpu;
        this.memory = builder.memory;
        this.hardDisk = builder.hardDisk;
        this.graphicsCard = builder.graphicsCard;
    }

    // Getter方法
    public String getCpu() {
        return cpu;
    }

    public String getMemory() {
        return memory;
    }

    public String getHardDisk() {
        return hardDisk;
    }

    public String getGraphicsCard() {
        return graphicsCard;
    }

    @Override
    public String toString() {
        return "Computer{" +
                "cpu='" + cpu + '\'' +
                ", memory='" + memory + '\'' +
                ", hardDisk='" + hardDisk + '\'' +
                ", graphicsCard='" + graphicsCard + '\'' +
                '}';
    }

    // 静态内部类:Builder
    public static class Builder {
        private String cpu;
        private String memory;
        private String hardDisk;
        private String graphicsCard;

        // 设置CPU,返回Builder实例以便链式调用
        public Builder setCpu(String cpu) {
            this.cpu = cpu;
            return this;
        }

        // 设置内存,返回Builder实例以便链式调用
        public Builder setMemory(String memory) {
            this.memory = memory;
            return this;
        }

        // 设置硬盘,返回Builder实例以便链式调用
        public Builder setHardDisk(String hardDisk) {
            this.hardDisk = hardDisk;
            return this;
        }

        // 设置显卡,返回Builder实例以便链式调用
        public Builder setGraphicsCard(String graphicsCard) {
            this.graphicsCard = graphicsCard;
            return this;
        }

        // 构建Computer对象
        public Computer build() {
            // 可以在这里添加参数验证逻辑
            if (cpu == null || memory == null || hardDisk == null) {
                throw new IllegalArgumentException("CPU、内存和硬盘是必需的");
            }
            return new Computer(this);
        }
    }
}

然后,使用建造者模式创建电脑对象:

public class BuilderPatternExample {
    public static void main(String[] args) {
        // 使用Builder创建电脑对象
        Computer gamingComputer = new Computer.Builder()
                .setCpu("Intel i9-12900K")
                .setMemory("32GB DDR5")
                .setHardDisk("2TB NVMe SSD")
                .setGraphicsCard("NVIDIA RTX 3080")
                .build();

        Computer officeComputer = new Computer.Builder()
                .setCpu("Intel i5-12400")
                .setMemory("16GB DDR4")
                .setHardDisk("512GB SSD")
                .build(); // 办公电脑可以不设置独立显卡

        System.out.println("游戏电脑配置:" + gamingComputer);
        System.out.println("办公电脑配置:" + officeComputer);
    }
}

如上是一个建造者模式的简单实现,是不是感觉超级简单,下面是经典的实现方式

 经典实现

// 1. 产品类:电脑
public class Computer {
    private String cpu;
    private String memory;
    private String hardDisk;
    private String graphicsCard;
    
    // 构造函数和Getter方法
    public Computer(String cpu, String memory, String hardDisk, String graphicsCard) {
        this.cpu = cpu;
        this.memory = memory;
        this.hardDisk = hardDisk;
        this.graphicsCard = graphicsCard;
    }
    
    @Override
    public String toString() {
        return "Computer{" +
                "cpu='" + cpu + '\'' +
                ", memory='" + memory + '\'' +
                ", hardDisk='" + hardDisk + '\'' +
                ", graphicsCard='" + graphicsCard + '\'' +
                '}';
    }
}

// 2. 抽象建造者接口
public interface ComputerBuilder {
    void buildCPU();
    void buildMemory();
    void buildHardDisk();
    void buildGraphicsCard();
    Computer getComputer();
}

// 3. 具体建造者:游戏电脑建造者
public class GamingComputerBuilder implements ComputerBuilder {
    private Computer computer;
    
    public GamingComputerBuilder() {
        this.computer = new Computer(null, null, null, null);
    }
    
    @Override
    public void buildCPU() {
        computer.setCpu("Intel i9-12900K");
    }
    
    @Override
    public void buildMemory() {
        computer.setMemory("32GB DDR5");
    }
    
    @Override
    public void buildHardDisk() {
        computer.setHardDisk("2TB NVMe SSD");
    }
    
    @Override
    public void buildGraphicsCard() {
        computer.setGraphicsCard("NVIDIA RTX 3080");
    }
    
    @Override
    public Computer getComputer() {
        return computer;
    }
}

// 3. 具体建造者:办公电脑建造者
public class OfficeComputerBuilder implements ComputerBuilder {
    private Computer computer;
    
    public OfficeComputerBuilder() {
        this.computer = new Computer(null, null, null, null);
    }
    
    @Override
    public void buildCPU() {
        computer.setCpu("Intel i5-12400");
    }
    
    @Override
    public void buildMemory() {
        computer.setMemory("16GB DDR4");
    }
    
    @Override
    public void buildHardDisk() {
        computer.setHardDisk("512GB SSD");
    }
    
    @Override
    public void buildGraphicsCard() {
        // 办公电脑可以不设置独立显卡
    }
    
    @Override
    public Computer getComputer() {
        return computer;
    }
}

// 4. 指挥者:控制构建过程
public class ComputerDirector {
    private ComputerBuilder builder;
    
    public ComputerDirector(ComputerBuilder builder) {
        this.builder = builder;
    }
    
    public void constructComputer() {
        builder.buildCPU();
        builder.buildMemory();
        builder.buildHardDisk();
        builder.buildGraphicsCard();
    }
    
    public Computer getComputer() {
        return builder.getComputer();
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        // 构建游戏电脑
        ComputerBuilder gamingBuilder = new GamingComputerBuilder();
        ComputerDirector director = new ComputerDirector(gamingBuilder);
        director.constructComputer();
        Computer gamingComputer = director.getComputer();
        
        // 构建办公电脑
        ComputerBuilder officeBuilder = new OfficeComputerBuilder();
        director = new ComputerDirector(officeBuilder);
        director.constructComputer();
        Computer officeComputer = director.getComputer();
        
        System.out.println("游戏电脑配置:" + gamingComputer);
        System.out.println("办公电脑配置:" + officeComputer);
    }
}

模式的优点

  1. 分离构建和表示:使得构建算法可以独立于产品的表示,提高了系统的可扩展性。
  2. 分步构建:可以分步骤构建一个复杂对象,允许在构建过程中进行不同的配置。
  3. 链式调用:通过链式调用方法设置属性,使代码更简洁易读。
  4. 参数验证:可以在build()方法中添加参数验证逻辑,确保对象的完整性。

模式的应用场景

  1. 复杂对象构建:当创建一个对象需要很多步骤,并且这些步骤的顺序可能不同。
  2. 可选参数较多:当一个类的构造函数有很多参数,特别是其中很多是可选参数时。
  3. 构建不同表示:当需要创建同一个产品的不同表示时。

与其他模式的比较

  • 工厂模式:工厂模式关注的是整体对象的创建,而建造者模式关注的是对象的分步构建。
  • 抽象工厂模式:抽象工厂模式返回的是一系列相关产品,而建造者模式返回的是一个完整的产品。

建造者模式在实际开发中非常常用,特别是在创建复杂对象时。它能够使代码更加清晰、灵活,并且易于维护。另外Lombok 的@Builder注解是一个强大的工具,它能自动生成流式 API 风格的 "建造者模式 (Builder Pattern)" 代码,从而避免编写大量样板代码。使用该注解可以让代码更简洁,同时保持建造者模式的优势。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2398389.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ES101系列07 | 分布式系统和分页

本篇文章主要讲解 ElasticSearch 中分布式系统的概念,包括节点、分片和并发控制等,同时还会提到分页遍历和深度遍历问题的解决方案。 节点 节点是一个 ElasticSearch 示例 其本质就是一个 Java 进程一个机器上可以运行多个示例但生产环境推荐只运行一个…

Spring AI Advisor机制

Spring AI Advisors 是 Spring AI 框架中用于拦截和增强 AI 交互的核心组件,其设计灵感类似于 WebFilter,通过链式调用实现对请求和响应的处理5。以下是关键特性与实现细节: 核心功能 ‌1. 请求/响应拦截‌ 通过 AroundAdvisor 接口动态修…

Vue3 + Vite:我的 Qiankun 微前端主子应用实践指南

前言 实践文章指南 vue微前端qiankun框架学习到项目实战,基座登录动态菜单及权限控制>>>>实战指南:Vue 2基座 Vue 3 Vite TypeScript微前端架构实现动态菜单与登录共享>>>>构建安全的Vue前后端分离架构:利用长Token与短Tok…

日语输入法怎么使用罗马字布局怎么安装日语输入法

今天帮客户安装日语输入法的时候遇到了一个纠结半天的问题,客户一直反馈说这个输入法不对,并不是他要的功能。他只需要罗马字的布局,而不是打出来字的假名。 片假名、平假名,就好像英文26个字母,用于组成日文单词。两…

数据结构:栈(Stack)和堆(Heap)

目录 内存(Memory)基础 程序是如何利用主存的? 🎯 静态内存分配 vs 动态内存分配 栈(stack) 程序执行过程与栈帧变化 堆(Heap) 程序运行时的主存布局 内存(Memo…

用 Vue 做一个轻量离线的“待办清单 + 情绪打卡”小工具

网罗开发 (小红书、快手、视频号同名) 大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等…

PostgreSQL数据库备份

文章目录 pg_dump 和 pg_dumpall使用 pg_dump 备份单个数据库示例 使用 pg_dumpall 备份整个数据库集群基本用法 恢复备份恢复 pg_dump 备份恢复 pg_dumpall 备份 Tips pg_dump 和 pg_dumpall 在 PostgreSQL 中,pg_dump 和 pg_dumpall 是两个常用的备份工具&#x…

js-day7

JS学习之旅-day7 1.事件流1.1 事件流与两个阶段说明1.2 事件捕获1.3 事件冒泡1.4 阻止1.5 解绑事件 2. 事件委托3. 其他事件3.1 页面加载事件3.2 页面滚动事件3.3 页面尺寸事件 4. 元素尺寸与位置 1.事件流 1.1 事件流与两个阶段说明 事件流指的是事件完整执行过程中的流动路…

解决Vditor加载Markdown网页很慢的问题(Vite+JS+Vditor)

1. 引言 在上一篇文章《使用Vditor将Markdown文档渲染成网页(ViteJSVditor)》中,详细介绍了通过Vditor将Markdown格式文档渲染成Web网页的过程,并且实现了图片格式居中以及图片源更换的功能。不过,笔者发现在加载这个渲染Markdown网页的时候…

鸿蒙5.0项目开发——横竖屏切换开发

横竖屏切换开发 【高心星出品】 文章目录 横竖屏切换开发运行效果窗口旋转配置module.json5的orientation字段调用窗口的setPreferredOrientation方法案例代码解析Index1页面代码:EntryAbility在module.json5的配置信息:Index页面的代码信息&#xff1…

Triton推理服务器部署YOLOv8(onnxruntime后端和TensorRT后端)

文章目录 一、Trition推理服务器基础知识1)推理服务器设计概述2)Trition推理服务器quickstart(1)创建模型仓库(Create a model Repository)(2)启动Triton (launching triton)并验证是否正常运行(3)发送推理请求(send a inference request)3)Trition推理服务器架…

TDengine 的 AI 应用实战——电力需求预测

作者: derekchen Demo数据集准备 我们使用公开的UTSD数据集里面的电力需求数据,作为预测算法的数据来源,基于历史数据预测未来若干小时的电力需求。数据集的采集频次为30分钟,单位与时间戳未提供。为了方便演示,按…

NLP学习路线图(二十一): 词向量可视化与分析

在自然语言处理(NLP)的世界里,词向量(Word Embeddings)犹如一场静默的革命。它将原本离散、难以捉摸的词语,转化为稠密、富含语义的连续向量,为机器理解语言铺平了道路。然而,这些向…

如何配置mvn镜像源为华为云

如何配置mvn镜像源为华为云 # 查找mvn 配置文件 mvn -X help:effective-settings | grep settings.xml# 配置mvn镜像源为华为云,/home/apache-maven-3.9.5/conf/settings.xml文件路径需要根据上一步中查询结果调整 cat > /home/apache-maven-3.9.5/conf/setting…

多模态大语言模型arxiv论文略读(105)

UnifiedMLLM: Enabling Unified Representation for Multi-modal Multi-tasks With Large Language Model ➡️ 论文标题:UnifiedMLLM: Enabling Unified Representation for Multi-modal Multi-tasks With Large Language Model ➡️ 论文作者:Zhaowei…

Pyhton中的命名空间包(Namespace Package)您了解吗?

在 Python 中,命名空间包(Namespace Package) 是一种特殊的包结构,它允许将模块分散在多个独立的目录中,但这些目录在逻辑上属于同一个包命名空间。命名空间包的核心特点是:没有 __init__.py 文件&#xff…

Azure DevOps Server 2022.2 补丁(Patch 5)

微软Azure DevOps Server的产品组在4月8日发布了2022.2 的第5个补丁。下载路径为:https://aka.ms/devops2022.2patch5 这个补丁的主要功能是修改了代理(Agent)二进制安装文件的下载路径;之前,微软使用这个CND(域名为vstsagentpackage.azuree…

手摸手还原vue3中reactive的get陷阱以及receiver的作用

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、实例是什么?二、new Prxoy三、实现代码1.引入代码2.读入数据 总结 前言 receiver不是为解决get陷阱而生,而是为解决Proxy中的this绑…

C++学习-入门到精通【13】标准库的容器和迭代器

C学习-入门到精通【13】标准库的容器和迭代器 目录 C学习-入门到精通【13】标准库的容器和迭代器一、标准模板库简介1.容器简介2.STL容器总览3.近容器4.STL容器的通用函数5.首类容器的通用typedef6.对容器元素的要求 二、迭代器简介1.使用istream_iterator输入,使用…

C# 面向对象特性

面向对象编程的三大基本特性是:封装、继承和多态。下面将详细介绍这三大特性在C#中的体现方式。 封装 定义:把对象的数据和操作代码组合在同一个结构中,这就是对象的封装性。 体现方式: 使用访问修饰符控制成员的可见性 通过属…