复杂对象的创建与组装 - 建造者模式(Builder Pattern)

news2025/1/5 8:18:33

建造者模式(Builder Pattern)

  • 建造者模式(Builder Pattern)
    • 建造者模式(Builder Pattern)概述
      • 建造者模式结构图
      • 代码
    • talk is cheap, show you my code
    • 总结

建造者模式(Builder Pattern)

建造者模式(Builder Pattern)是一种创建型设计模式,它允许你分步骤构建复杂对象。该模式将一个复杂对象的构造与它的表示分离,使得同样的构建过程可以创建不同的表示。通过使用建造者模式,你可以避免大量参数化构造函数或多个重载构造函数带来的代码混乱,并且能够更容易地管理复杂的对象创建逻辑。

概念还是有一点抽象的
举个例子,作为一个平时打打游戏的同学,有时候会玩一种赛车游戏。赛车是可以自己定义与组装的。游戏中提供了各种各样的轮子,车体,引擎,悬架。。。 我们可以通过使用这些组件灵活地拼装出我们想要地自定义赛车。那么对这款游戏来说,我们自定义出来地车会有很多种类,那我们怎么实现这个效果呢? 使用建造者模式,具体细节请继续往下阅读。

建造者模式(Builder Pattern)概述

建造者模式结构图

在这里插入图片描述

代码

  1. 产品(Product): 最终被构建出来的复杂对象。它可以是一个具体的类,也可以是包含多个组件的对象。产品对象并不知道如何创建自己;相反,它依赖于建造者来完成其组装。
public class Product {
    private List<String> parts = new ArrayList<>();

    public void add(String part) {
        parts.add(part);
    }

    public void show() {
        System.out.println("Product contains the following parts:");
        for (String part : parts) {
            System.out.println(part);
        }
    }
}
  1. 抽象建造者(Builder):接口或抽象类,声明了用于构建各个组件的方法。具体建造者必须实现这些方法,以提供特定类型的对象构建逻辑。
public interface Builder {
    void buildPartA();
    void buildPartB();
    Product getResult();
}
  1. 具体建造者(ConcreteBuilder):实现了 Builder 接口的具体类。每个具体建造者都对应一种特定的产品类型,并负责一步一步地构建该产品的不同部分。
public class ConcreteBuilder implements Builder {
    private Product product = new Product();

    @Override
    public void buildPartA() {
        product.add("PartA");
    }

    @Override
    public void buildPartB() {
        product.add("PartB");
    }

    @Override
    public Product getResult() {
        return product;
    }
}
  1. 指挥者(Director):指挥者类负责控制和协调建造者的操作顺序。它不直接创建产品实例,而是调用建造者提供的方法来逐步构建产品。这样做的好处是可以改变构建过程中的步骤顺序,而不影响客户端代码。
public class Director {
    private Builder builder;

    public Director(Builder builder) {
        this.builder = builder;
    }

    public void construct() {
        builder.buildPartA();
        builder.buildPartB();
    }
}

talk is cheap, show you my code

我们还是实现我们开头举的那个例子,实现一个可以自定义组装汽车的建造者模式代码。

class Car {
    private String body;
    private String engine;
    private String wheels;
    private String seats;
 
    // 私有构造函数,防止外部直接实例化
    private Car(CarBuilder builder) {
        this.body = builder.body;
        this.engine = builder.engine;
        this.wheels = builder.wheels;
        this.seats = builder.seats;
    }
 
    // 静态内部类,用于创建CarBuilder实例
    public static class CarBuilder {
        // 汽车部件
        protected String body;
        protected String engine;
        protected String wheels;
        protected String seats;
 
        // 设置车身的方法
        public CarBuilder setBody(String body) {
            this.body = body;
            return this; // 返回当前对象,支持链式调用
        }
 
        // 设置发动机的方法
        public CarBuilder setEngine(String engine) {
            this.engine = engine;
            return this;
        }
 
        // 设置车轮的方法
        public CarBuilder setWheels(String wheels) {
            this.wheels = wheels;
            return this;
        }
 
        // 设置座椅的方法
        public CarBuilder setSeats(String seats) {
            this.seats = seats;
            return this;
        }
 
        // 构建汽车的方法
        public Car build() {
            return new Car(this);
        }
    }
 
    // 展示汽车信息的方法
    @Override
    public String toString() {
        return "Car{" +
                "body='" + body + '\'' +
                ", engine='" + engine + '\'' +
                ", wheels='" + wheels + '\'' +
                ", seats='" + seats + '\'' +
                '}';
    }
}
 
// 具体建造者类:豪华车建造者
class LuxuryCarBuilder extends Car.CarBuilder {
    @Override
    public CarBuilder setBody(String body) {
        super.setBody("Luxury Body");
        return this;
    }
 
    @Override
    public CarBuilder setEngine(String engine) {
        super.setEngine("V8 Engine");
        return this;
    }
 
    @Override
    public CarBuilder setWheels(String wheels) {
        super.setWheels("Alloy Wheels");
        return this;
    }
 
    @Override
    public CarBuilder setSeats(String seats) {
        super.setSeats("Leather Seats");
        return this;
    }
}
 
// 具体建造者类:经济型车建造者
class EconomyCarBuilder extends Car.CarBuilder {
    @Override
    public CarBuilder setBody(String body) {
        super.setBody("Economy Body");
        return this;
    }
 
    @Override
    public CarBuilder setEngine(String engine) {
        super.setEngine("4 Cylinder Engine");
        return this;
    }
 
    @Override
    public CarBuilder setWheels(String wheels) {
        super.setWheels("Steel Wheels");
        return this;
    }
 
    @Override
    public CarBuilder setSeats(String seats) {
        super.setSeats("Fabric Seats");
        return this;
    }
}
 
// 指挥者类:汽车工厂
class CarDirector {
    private Car.CarBuilder builder;
 
    public CarDirector(Car.CarBuilder builder) {
        this.builder = builder;
    }
 
    // 指挥构建汽车的方法
    public Car constructCar() {
        return builder
                .setBody("Default Body") // 可以被具体建造者覆盖
                .setEngine("Default Engine") // 可以被具体建造者覆盖
                .setWheels("Default Wheels") // 可以被具体建造者覆盖
                .setSeats("Default Seats") // 可以被具体建造者覆盖
                .build();
    }
}
 
// 客户端代码
public class Main {
    public static void main(String[] args) {
        // 创建豪华车
        CarDirector luxuryDirector = new CarDirector(new LuxuryCarBuilder());
        Car luxuryCar = luxuryDirector.constructCar();
        System.out.println(luxuryCar);
 
        // 创建经济型车
        CarDirector economyDirector = new CarDirector(new EconomyCarBuilder());
        Car economyCar = economyDirector.constructCar();
        System.out.println(economyCar);
    }
}

在这个例子中,Car类有一个私有构造函数,只能通过CarBuilder内部类来创建实例。CarBuilder是一个抽象建造者,提供了设置汽车各个部件的方法,并返回当前对象以支持链式调用。LuxuryCarBuilder和EconomyCarBuilder是具体建造者,它们覆盖了CarBuilder中的方法以提供不同类型的汽车部件。CarDirector是指挥者,它使用CarBuilder接口来构建汽车,但允许具体建造者提供特定的实现。

客户端代码通过创建CarDirector实例并传递具体的CarBuilder来构建不同类型的汽车。这样,客户端代码与具体的汽车构建过程解耦,只需要知道如何创建指挥者和选择具体的建造者即可。

总结

建造者模式优点:

  • 减少大量的构造函数参数:当一个类有很多可选参数时,可以通过建造者模式来避免长而复杂的构造函数签名。
  • 提高代码可读性:通过链式调用(Fluent Interface),可以使对象创建更加直观和易懂。
  • 易于扩展:如果需要添加新的组件或改变构建逻辑,只需新增具体建造者类,而不需要修改现有代码。
  • 符合单一职责原则:建造者模式让每个类只专注于一件事,即构建某个特定类型的产品。

建造者模式的应用场景

  • 复杂对象创建
  • 多步骤过程
  • 变种对象

建造者模式是一个非常有用的设计模式,特别是在需要处理具有多个可选参数或复杂创建逻辑的对象时。它帮助开发者更好地组织代码,提高系统的灵活性和可维护性。

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

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

相关文章

云计算课程报告实验-WordCount算法实验 过程记录

内容描述 本实验指导书通过在华为鲲鹏上&#xff0c;编译运行WordCount程序。完成实验操作后&#xff0c;读者会掌握简单的程序编写&#xff0c;如WordCount中的getWords、countWords、treeMerge。 实验环境 华为鲲鹏云主机、openEuler 20.03操作系统&#xff1b;安装mpich-3…

springboot533图书管理系统(论文+源码)_kaic

摘 要 传统信息的管理大部分依赖于管理人员的手工登记与管理&#xff0c;然而&#xff0c;随着近些年信息技术的迅猛发展&#xff0c;让许多比较老套的信息管理模式进行了更新迭代&#xff0c;图书信息因为其管理内容繁杂&#xff0c;管理数量繁多导致手工进行处理不能满足广…

【服务器开发及部署】code-server 显示git graph

在开发一些linux上的内容的时候进程需要在开发机和生产部署上花费大量的时间。 为了解决上述问题,我们今天介绍一款在服务上开发的思路 git + code server + 宝塔 其中需要处理一些问题,此处都有交代 步骤 安装宝塔安装code-server配置插件配置浏览器处理的问题 git版本过低,…

【游戏设计原理】41 - 游戏的核心

1. 如何理解&#xff1f; 这条原理主要在讲述“游戏核心”这一概念的重要性及其在游戏开发中的作用。游戏的核心是指决定游戏整体玩法和体验的核心元素&#xff0c;它通常是游戏的主要机制、目标或动作方式。理解这一原理时&#xff0c;我们可以从以下几个层面来考虑&#xff…

win11 vs2022 opencv 4.10 camshift示例程序运行

记录win11 vs2022 opencv 4.10下 camshift等示例程序的单步debug启动方式&#xff0c;方便了解源码。 debug版本编译通过&#xff0c;但运行时报出大量日志信息(部分dll加载FAILED后会自动找兼容dll)。但也能继续运行&#xff0c;效果如下 release版本可以直接运行&#xff0…

数据结构漫游记:初识栈(stack)

嘿&#xff0c;各位技术潮人&#xff01;好久不见甚是想念。生活就像一场奇妙冒险&#xff0c;而编程就是那把超酷的万能钥匙。此刻&#xff0c;阳光洒在键盘上&#xff0c;灵感在指尖跳跃&#xff0c;让我们抛开一切束缚&#xff0c;给平淡日子加点料&#xff0c;注入满满的pa…

人工智能知识分享第五天-正则化.损失函数案例

正则化 欠拟合与过拟合 过拟合&#xff1a;一个假设 在训练数据上能够获得比其他假设更好的拟合&#xff0c; 但是在测试数据集上却不能很好地拟合数据 (体现在准确率下降)&#xff0c;此时认为这个假设出现了过拟合的现象。(模型过于复杂) 欠拟合&#xff1a;一个假设 在训…

CSS2笔记

一、CSS基础 1.CSS简介 2.CSS的编写位置 2.1 行内样式 2.2 内部样式 2.3 外部样式 3.样式表的优先级 4.CSS语法规范 5.CSS代码风格 二、CSS选择器 1.CSS基本选择器 通配选择器元素选择器类选择器id选择器 1.1 通配选择器 1.2 元素选择器 1.3 类选择器 1.4 ID选择器 1.5 基…

如何在 Ubuntu 22.04 上优化 Apache 以应对高流量网站教程

简介 在本教程中&#xff0c;我们将学习如何优化 Apache 以应对高流量网站。 当运行高流量网站时&#xff0c;确保你的 Apache Web 服务器得到优化对于有效处理负载至关重要。在本指南中&#xff0c;我们将介绍配置 Apache 以提高性能和可扩展性的基本技巧。 为高流量网站优…

安装教程:慧集通集成平台(DataLinkX)智能体客户端安装操作(Linux/windows/mac)

1.下载客户端 使用提供的账号登录集成平台后台(https://www.datalinkx.cn/),点击左侧菜单栏【智能体】→【智能体】进入到智能体列表界面&#xff0c;在该界面我们找到功能栏中的下载按钮点击则会弹出下载界面&#xff0c;在该界面我们可以选择不同的系统操作系统来下载对应版…

Spring boot + Hibernate + MySQL实现用户管理示例

安装MySQL Windows 11 Mysql 安装及常用命令_windows11 mysql-CSDN博客 整体目录 pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLS…

大模型Weekly 03|OpenAI o3发布;DeepSeek-V3上线即开源!

大模型Weekly 03&#xff5c;OpenAI o3发布&#xff1b;DeepSeek-V3上线即开源&#xff01;DeepSeek-V3上线即开源&#xff1b;OpenAI 发布高级推理模型 o3https://mp.weixin.qq.com/s/9qU_zzIv9ibFdJZ5cTocOw?token47960959&langzh_CN 「青稞大模型Weekly」&#xff0c;持…

电路学习之前言

1.作为一名嵌入式开发者&#xff0c;去学习电路是必经之路。如果是一名嵌入式软件开发者&#xff0c;可能对电路和硬件的开发要求是能看懂电路图即可&#xff0c;但是&#xff0c;学习电路可以进一步提高看电路图的能力&#xff0c;可以提升自己的整体实力水平。而且&#xff0…

Java反射详解(二)

上一篇博客&#xff1a;Java反射详解&#xff08;一&#xff09; 写在前面&#xff1a;大家好&#xff01;我是晴空๓。如果博客中有不足或者的错误的地方欢迎在评论区或者私信我指正&#xff0c;感谢大家的不吝赐教。我的唯一博客更新地址是&#xff1a;https://ac-fun.blog.c…

zentao ubuntu上安装

#下载ZenTaoPMS-21.2-zbox_amd64.tar.gz&#xff08;https://www.zentao.net/downloads.html&#xff09; https://dl.zentao.net/zentao/21.2/ZenTaoPMS-21.2-zbox_amd64.tar.gzcd /opt tar -zxvf ZenTaoPMS-21.2-zbox_amd64.tar.gz#启动 /opt/zbox/zbox start /opt/zbox/zbox…

逆境清醒文章总目录表

逆境清醒文章总目录表 零、时光宝盒&#x1f33b; &#xff08;https://blog.csdn.net/weixin_69553582 逆境清醒&#xff09; 《你的答案》歌曲原唱&#xff1a;阿冗&#xff0c;填 词&#xff1a;林晨阳、刘涛&#xff0c;谱曲&#xff1a;刘涛 也许世界就这样&#xff0c…

【嵌入式硬件】嵌入式显示屏接口

数字显示串行接口&#xff08;Digital Display Serial Interface&#xff09; SPI 不过多赘述。 I2C-bus interface 不过多赘述 MIPI DSI MIPI (Mobile Industry Processor Interface) Alliance, DSI (Display Serial Interface) 一般用于移动设备&#xff0c;下面是接口…

AI证件照制作 API 快速生成示例

AI证件照制作 API 快速生成证件照示例 本文将介绍一种 AI证件照制作 API 对接说明&#xff0c;它是可以通过输入人像照片URL以及自己喜欢的模板来制作各种风格的证件照。 接下来介绍下 AI证件照制作 API 的对接说明。 申请流程 要使用 API&#xff0c;需要先到 AI证件照制作…

一个在ios当中采用ObjectC和opencv来显示图片的实例

前言 在ios中采用ObjectC编程利用opencv来显示一张图片&#xff0c;并简单绘图。听上去似乎不难&#xff0c;但是实际操作下来&#xff0c;却不是非常的容易的。本文较为详细的描述了这个过程&#xff0c;供后续参考。 一、创建ios工程 1.1、选择ios工程类型 1.2、选择接口模…

006-Jetpack Compose for Android之传感器数据

需求分析 想要看看手机的传感器数据&#xff0c;看看滤波一下能玩点什么无聊的。先搞个最简单的&#xff0c;手机本身的姿态。 需求&#xff1a;采集手机姿态数据&#xff0c;显示在界面上。 那么我们需要&#xff1a; 一个文本标签类似的控件&#xff0c;显示手机姿态数据…