生成器模式深入解析与 Spring 源码应用

news2025/4/21 10:52:30

摘要

本文以生成器模式为研究对象,采用通俗易懂的表述方式,详细阐释其核心概念与运行机制。通过构建游戏角色创建、电商订单生成等实际 Java 案例,直观呈现该模式在复杂对象构建中的应用优势。同时,深入剖析 Spring 框架源码,揭示生成器模式在 Bean 创建过程中的关键作用。旨在帮助开发者全面理解生成器模式的应用场景与实践价值,为软件开发过程中设计模式的合理运用提供有效参考。

关键词

生成器模式;设计模式;Spring 框架;源码解析;Java 编程

一、引言

在软件开发领域,对象创建是一项基础且重要的操作。当面对复杂对象,其构建涉及多个组成部分与步骤逻辑时,常规创建方式易导致代码耦合度高、可维护性差等问题。设计模式作为经过实践验证的通用解决方案,能够有效应对此类挑战。生成器模式作为创建型设计模式中的一员,专注于将复杂对象的构建过程与最终表示进行分离,使得同一构建流程可生成不同表现形式的对象。

Spring 框架作为 Java 企业级应用开发的主流框架,凭借其强大的功能与高度的灵活性被广泛使用。其内部大量运用设计模式,以实现高内聚、低耦合的架构设计目标。深入研究 Spring 源码中生成器模式的应用,不仅有助于理解 Spring 的运行原理,还能为开发者在实际项目中应用设计模式提供宝贵经验。本文将结合丰富的实际案例与 Spring 源码解析,对生成器模式展开全面且深入的探讨。

二、生成器模式概述

2.1 定义与核心概念

生成器模式(Builder Pattern)属于创建型设计模式,其核心在于将复杂对象的构建过程与最终表现形式相分离,从而使相同的构建过程能够产生不同结构或内容的对象。该模式包含四个核心角色:

  1. 产品(Product):即需要创建的复杂对象,由多个不同部件组成,例如汽车由车身、发动机、轮胎等部件构成 。

  2. 抽象生成器(Builder):定义了创建产品各个部件的抽象方法,以及用于获取最终产品的方法,为具体生成器提供统一的操作规范。

  3. 具体生成器(Concrete Builder):实现抽象生成器定义的方法,负责具体构建产品的各个部件,并将其组装成完整的产品。

  4. 指挥者(Director):负责安排产品构建的具体步骤和顺序,通过调用生成器的方法来完成产品的创建,它并不关心产品的具体构建细节,只关注构建流程。

2.2 优点与应用场景

生成器模式具有以下显著优点:

  1. 职责分离:将对象构建过程与表示分离,使代码结构更加清晰,每个类专注于自身职责,提高了代码的可读性和可维护性。

  2. 灵活性高:便于应对复杂对象的创建需求,通过不同的具体生成器可以创建出具有不同特性的产品,满足多样化的业务需求 。

  3. 可扩展性强:当需要新增产品类型或修改产品构建逻辑时,只需添加或修改具体生成器类,不影响其他部分代码,符合开闭原则。

  4. 代码复用:具体生成器类的方法可以被复用,减少代码冗余,提高开发效率。

生成器模式适用于以下场景:

  1. 复杂对象创建:当创建的对象包含多个部件,且构建过程较为复杂时,使用生成器模式能够有效管理构建流程。

  2. 步骤化构建:若对象创建过程需要按照特定步骤进行,且步骤可能会发生变化,生成器模式可以灵活适应这种变化。

  3. 多样化产品生成:期望通过同一构建过程生成不同表现形式的产品,如不同配置的电脑、不同款式的家具等。

三、生成器模式实际案例分析

3.1 游戏角色创建案例

3.1.1 案例背景

在游戏开发中,游戏角色是一个复杂的对象,其创建涉及角色的种族、职业、装备、技能等多个方面。不同类型的角色(如战士、法师、刺客)在这些属性上存在差异,且创建流程也有所不同。使用生成器模式可以很好地管理游戏角色的创建过程,使代码更加清晰和易于维护。

3.1.2 代码实现
  1. 定义产品类(游戏角色)
public class GameCharacter {

private String race;

private String profession;

private String equipment;

private String skills;

public void setRace(String race) {

this.race = race;

}

public void setProfession(String profession) {

this.profession = profession;

}

public void setEquipment(String equipment) {

this.equipment = equipment;

}

public void setSkills(String skills) {

this.skills = skills;

}

public void display() {

System.out.println("游戏角色信息:");

System.out.println("种族:" + race);

System.out.println("职业:" + profession);

System.out.println("装备:" + equipment);

System.out.println("技能:" + skills);

}

}
  1. 定义抽象生成器类
public abstract class CharacterBuilder {

protected GameCharacter character = new GameCharacter();

public abstract void buildRace();

public abstract void buildProfession();

public abstract void buildEquipment();

public abstract void buildSkills();

public GameCharacter getCharacter() {

return character;

}

}
  1. 定义具体生成器类(战士角色生成器)
public class WarriorBuilder extends CharacterBuilder {

@Override

public void buildRace() {

character.setRace("人类");

}

@Override

public void buildProfession() {

character.setProfession("战士");

}

@Override

public void buildEquipment() {

character.setEquipment("重型铠甲、长剑");

}

@Override

public void buildSkills() {

character.setSkills("冲锋、斩杀");

}

}
  1. 定义具体生成器类(法师角色生成器)
public class MageBuilder extends CharacterBuilder {

@Override

public void buildRace() {

character.setRace("精灵");

}

@Override

public void buildProfession() {

character.setProfession("法师");

}

@Override

public void buildEquipment() {

character.setEquipment("魔法长袍、法杖");

}

@Override

public void buildSkills() {

character.setSkills("火球术、暴风雪");

}

}
  1. 定义指挥者类
public class CharacterDirector {

private CharacterBuilder builder;

public CharacterDirector(CharacterBuilder builder) {

this.builder = builder;

}

public GameCharacter construct() {

builder.buildRace();

builder.buildProfession();

builder.buildEquipment();

builder.buildSkills();

return builder.getCharacter();

}

}
  1. 测试代码
public class Main {

public static void main(String[] args) {

// 创建战士角色

CharacterBuilder warriorBuilder = new WarriorBuilder();

CharacterDirector warriorDirector = new CharacterDirector(warriorBuilder);

GameCharacter warrior = warriorDirector.construct();

warrior.display();

// 创建法师角色

CharacterBuilder mageBuilder = new MageBuilder();

CharacterDirector mageDirector = new CharacterDirector(mageBuilder);

GameCharacter mage = mageDirector.construct();

mage.display();

}

}
3.1.3 案例总结

通过游戏角色创建案例可以看到,生成器模式将游戏角色的构建过程与角色的最终表现分离。不同类型的角色由相应的具体生成器负责构建,指挥者按照固定流程调用生成器方法完成角色创建。当需要新增角色类型时,仅需创建新的具体生成器类,无需修改其他代码,充分体现了生成器模式的扩展性和灵活性。

3.2 电商订单生成案例

3.2.1 案例背景

在电商系统中,订单是一个复杂的对象,其生成涉及订单基本信息(订单号、下单时间)、用户信息、商品信息、支付信息等多个部分。不同类型的订单(如普通订单、促销订单)在信息处理和生成流程上可能存在差异。利用生成器模式能够有效管理订单的生成过程,使代码结构更加清晰。

3.2.2 代码实现
  1. 定义产品类(订单)
public class Order {

private String orderNumber;

private String orderTime;

private String userInfo;

private String productInfo;

private String paymentInfo;

public void setOrderNumber(String orderNumber) {

this.orderNumber = orderNumber;

}

public void setOrderTime(String orderTime) {

this.orderTime = orderTime;

}

public void setUserInfo(String userInfo) {

this.userInfo = userInfo;

}

public void setProductInfo(String productInfo) {

this.productInfo = productInfo;

}

public void setPaymentInfo(String paymentInfo) {

this.paymentInfo = paymentInfo;

}

public void showOrder() {

System.out.println("订单信息:");

System.out.println("订单号:" + orderNumber);

System.out.println("下单时间:" + orderTime);

System.out.println("用户信息:" + userInfo);

System.out.println("商品信息:" + productInfo);

System.out.println("支付信息:" + paymentInfo);

}

}
  1. 定义抽象生成器类
public abstract class OrderBuilder {

protected Order order = new Order();

public abstract void buildOrderNumber();

public abstract void buildOrderTime();

public abstract void buildUserInfo();

public abstract void buildProductInfo();

public abstract void buildPaymentInfo();

public Order getOrder() {

return order;

}

}
  1. 定义具体生成器类(普通订单生成器)
public class NormalOrderBuilder extends OrderBuilder {

@Override

public void buildOrderNumber() {

order.setOrderNumber("NO" + System.currentTimeMillis());

}

@Override

public void buildOrderTime() {

order.setOrderTime(java.time.LocalDateTime.now().toString());

}

@Override

public void buildUserInfo() {

order.setUserInfo("用户ID:123456");

}

@Override

public void buildProductInfo() {

order.setProductInfo("商品名称:手机,数量:1");

}

@Override

public void buildPaymentInfo() {

order.setPaymentInfo("支付方式:支付宝,金额:5999元");

}

}
  1. 定义具体生成器类(促销订单生成器)
public class PromotionOrderBuilder extends OrderBuilder {

@Override

public void buildOrderNumber() {

order.setOrderNumber("PNO" + System.currentTimeMillis());

}

@Override

public void buildOrderTime() {

order.setOrderTime(java.time.LocalDateTime.now().toString());

}

@Override

public void buildUserInfo() {

order.setUserInfo("用户ID:123456");

}

@Override

public void buildProductInfo() {

order.setProductInfo("商品名称:电视,数量:1,促销折扣:8折");

}

@Override

public void buildPaymentInfo() {

order.setPaymentInfo("支付方式:微信支付,金额:3199元");

}

}
  1. 定义指挥者类
public class OrderDirector {

private OrderBuilder builder;

public OrderDirector(OrderBuilder builder) {

this.builder = builder;

}

public Order construct() {

builder.buildOrderNumber();

builder.buildOrderTime();

builder.buildUserInfo();

builder.buildProductInfo();

builder.buildPaymentInfo();

return builder.getOrder();

}

}
  1. 测试代码
public class Main {

public static void main(String[] args) {

// 创建普通订单

OrderBuilder normalOrderBuilder = new NormalOrderBuilder();

OrderDirector normalOrderDirector = new OrderDirector(normalOrderBuilder);

Order normalOrder = normalOrderDirector.construct();

normalOrder.showOrder();

// 创建促销订单

OrderBuilder promotionOrderBuilder = new PromotionOrderBuilder();

OrderDirector promotionOrderDirector = new OrderDirector(promotionOrderBuilder);

Order promotionOrder = promotionOrderDirector.construct();

promotionOrder.showOrder();

}

}
3.2.3 案例总结

在电商订单生成案例中,生成器模式将订单的构建过程与订单的最终呈现分离。不同类型的订单由不同的具体生成器负责构建,指挥者控制订单的生成步骤。当业务需求发生变化,如新增订单类型或修改订单信息生成逻辑时,只需调整相应的具体生成器类,保证了系统的可维护性和扩展性。

四、Spring 源码中生成器模式的应用

4.1 Spring 框架简介

Spring 框架是一个开源的 Java 应用框架,为企业级应用开发提供了全面的解决方案。它采用依赖注入(Dependency Injection,DI)、面向切面编程(Aspect Oriented Programming,AOP)等核心技术,帮助开发者构建松耦合、可扩展的应用架构。Spring 框架包含多个模块,如 Spring Core、Spring Context、Spring MVC 等,广泛应用于 Web 应用开发、微服务架构搭建等领域 。

4.2 Spring 中生成器模式在 Bean 创建中的应用

在 Spring 框架中,Bean 的创建是一个复杂且关键的过程,涉及实例化、属性注入、初始化等多个步骤。Spring 巧妙地运用生成器模式来管理 Bean 的创建流程,以提升代码的可维护性和扩展性。在 Spring 中,BeanDefinition用于存储 Bean 的定义信息,包括 Bean 的类型、属性值、依赖关系等;BeanFactory负责依据BeanDefinition创建 Bean 实例;而BeanWrapper和BeanWrapperImpl类在 Bean 创建过程中扮演着类似生成器的角色。

BeanWrapper是一个接口,它定义了一系列操作 Bean 属性的方法,如获取和设置属性值、获取 Bean 的类型等。BeanWrapperImpl是BeanWrapper的具体实现类,负责具体执行 Bean 属性的操作和实例化工作。以下是简化后的相关代码结构:

  1. **BeanWrapper****接口
public interface BeanWrapper {

Object getWrappedInstance();

Class<?> getWrappedClass();

void setPropertyValue(String propertyName, Object value) throws BeansException;

Object getPropertyValue(String propertyName) throws BeansException;

// 其他属性操作方法

}
  1. **BeanWrapperImpl****类
public class BeanWrapperImpl implements BeanWrapper {

private Object wrappedInstance;

private Class<?> wrappedClass;

public BeanWrapperImpl(Object object) {

this.wrappedInstance = object;

this.wrappedClass = object.getClass();

}

@Override

public Object getWrappedInstance() {

return wrappedInstance;

}

@Override

public Class<?> getWrappedClass() {

return wrappedClass;

}

@Override

public void setPropertyValue(String propertyName, Object value) throws BeansException {

// 通过反射设置属性值的具体逻辑

try {

PropertyDescriptor pd = new PropertyDescriptor(propertyName, wrappedClass);

Method writeMethod = pd.getWriteMethod();

writeMethod.invoke(wrappedInstance, value);

} catch (Exception e) {

throw new BeansException("Failed to set property value", e);

}

}

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

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

相关文章

云效部署实现Java项目自动化部署图解

前言 记录下使用云效部署Java项目&#xff0c;实现java项目一键化自动化部署。 云效流程说明&#xff1a; 1.云效拉取最新git代码后 2.进行maven编译打包后&#xff0c;上传到指定服务器目录 3.通过shell脚本&#xff0c;先kill java项目后&#xff0c;通过java -jar 启动项…

0801ajax_mock-网络ajax请求1-react-仿低代码平台项目

0 vite配置proxy代理 vite.config.ts代码如下图所示&#xff1a; import { defineConfig } from "vite"; import react from "vitejs/plugin-react";// https://vite.dev/config/ export default defineConfig({plugins: [react()],server: {proxy: {&qu…

基于Python智能体API的Word自动化排版系统:从零构建全流程模块化工作流与版本控制研究

基于Python智能体API的Word自动化排版系统:从零构建全流程模块化工作流与版本控制实践研究 1. 引言2. 研究背景与意义3. 自动排版工作流的设计原理3.1 文档内容提取与解析3.2 样式参数与格式化规则3.3 智能体API接口调用3.4 自动生成与批量处理3.5 与生成式AI的协同4. 系统架构…

Java【网络原理】(4)HTTP协议

目录 1.前言 2.正文 2.1自定义协议 2.2HTTP协议 2.2.1抓包工具 2.2.2请求响应格式 2.2.2.1URL 2.2.2.2urlencode 2.2.3认识方法 2.2.3.1GET与POST 2.2.3.2PUT与DELETE 2.2.4请求头关键属性 3.小结 1.前言 哈喽大家好啊&#xff0c;今天来继续给大家带来Java中网络…

每天学一个 Linux 命令(27):head

​​可访问网站查看,视觉品味拉满: http://www.616vip.cn/27/index.html head 是 Linux 中用于查看文件开头部分内容的命令,默认显示文件前 10 行,适合快速预览文件结构或日志头部信息。 命令格式 head [选项] [文件]常用选项 选项说明-n <行数>指定显示前 N 行(如…

【2025软考高级架构师】——计算机系统基础(7)

摘要 本文主要介绍了计算机系统的组成&#xff0c;包括硬件和软件两大部分。硬件由处理器、存储器、总线、接口和外部设备等组成&#xff0c;软件则涵盖系统软件和应用软件。文章还详细阐述了冯诺依曼计算机的组成结构&#xff0c;包括 CPU、主存储器、外存等&#xff0c;并解…

LeetCode 打家劫舍+删除并获得点数

题目描述 打家劫舍题目传送门1 删除并获得点数传送门2 思路 这两道题看似毫无关系&#xff0c;但竟然可以用桶数组联系起来&#xff01;&#xff01; 先说打家劫舍这道题 限制条件是不能走相邻的屋&#xff0c;再联想到跳台阶&#xff08;走一格或两格&#xff09;&#x…

图解MCP:Model Context Protocol

&#x1f9e0; 向所有学习者致敬&#xff01; “学习不是装满一桶水&#xff0c;而是点燃一把火。” —— 叶芝 我的博客主页&#xff1a; https://lizheng.blog.csdn.net &#x1f310; 欢迎点击加入AI人工智能社区&#xff01; &#x1f680; 让我们一起努力&#xff0c;共创…

【网络】数据链路层知识梳理

全是通俗易懂的讲解&#xff0c;如果你本节之前的知识都掌握清楚&#xff0c;那就速速来看我的笔记吧~ 自己写自己的八股&#xff01;让未来的自己看懂&#xff01; &#xff08;全文手敲&#xff0c;受益良多&#xff09; 数据链路层 我们来重新理解一下这个图&#xff1a;…

积木报表查询出现jdbc.SQLServerException: 对象名 ‘user_tab_comment 的解决方法

目录 前言1. 问题所示2. 解决方法前言 🤟 找工作,来万码优才:👉 #小程序://万码优才/r6rqmzDaXpYkJZF 爬虫神器,无代码爬取,就来:bright.cn 1. 问题所示 使用帆软报表无错,后续使用积木报表查询出错: 没有显示报表: 具体错误信息如下:

数字孪生废气处理工艺流程

图扑数字孪生废气处理工艺流程系统。通过精准 3D 建模&#xff0c;对废气收集、预处理、净化、排放等全流程进行 1:1 数字化复刻&#xff0c;实时呈现设备运行参数、污染物浓度变化等关键数据。 借助图扑可视化界面&#xff0c;管理者可直观掌握废气处理各环节状态&#xff0c…

【某比特币网址请求头部sign签名】RSA加密逆向分析

目标&#xff1a;aHR0cDovL21lZ2FiaXQudmlwL21hcmtldA 直接搜索sign不方便定位&#xff0c;可以换个思路搜asi_uuid或者user_info 为什么搜这个&#xff0c;因为都是请求头里面的参数&#xff0c;基本上会在一起 实际上就是Object(h.a)((new Date).getTime()) 直接在这里打断点…

基于WebRTC技术的EasyRTC:支持任意平台设备的实时音视频通信解决方案

一、技术架构与核心优势 EasyRTC是一套基于WebRTC技术的实时音视频通信框架&#xff0c;旨在为开发者提供高效、稳定、跨平台的通信解决方案。其核心优势在于支持任意平台设备&#xff0c;包括Web端、移动端、桌面端和嵌入式设备&#xff0c;真正实现“一次开发&#xff0c;多…

DNS解析失败怎么解决?

在互联网时代&#xff0c;畅快地浏览网页、使用各类网络服务已成为生活常态。然而&#xff0c;当屏幕突然弹出 “DNS解析失败”的提示&#xff0c;原本顺畅的网络连接戛然而止&#xff0c;让人倍感困扰。DNS即域名系统&#xff0c;它如同互联网的 “电话簿”&#xff0c;负责将…

2025年4月19日

1.英语 1.单词 2.翻译 老年人食堂 In recent years, elderly population in China has continued to grow. The Chinese government is taking various measures to advance the construction of the elderly care service system and to make the later lives of the elde…

【Vue】组件通信(Props/Emit、EventBus、Provide/Inject)

个人主页&#xff1a;Guiat 归属专栏&#xff1a;Vue 文章目录 1. Props/Emit 父子组件通信1.1 Props 向下传递数据1.2 Emit 向上传递事件 2. EventBus 跨组件通信2.1 创建事件总线2.2 使用事件总线2.3 EventBus 优缺点 3. Provide/Inject 深层组件通信3.1 基本使用3.2 响应式处…

QT实现串口透传的功能

在一些产品的开发的时候&#xff0c;需要将一个串口的数据发送给另外一个串口进行转发。 具体的代码如下&#xff1a; #include "mainwindow.h" #include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::Ma…

动态规划入门:背包问题求具体方案(以0-1背包问题为例)

本质&#xff1a;有向图最短&#xff08;长&#xff09;路问题 字典序最小方案&#xff1f;--贪心思路&#xff1f;&#xff08;本题未使用&#xff09; 分析第一个物品&#xff1a; 写代码时tip&#xff1a;要考虑“边读边做”还是“先读后做” #include<iostream> #i…

WEMOS LOLIN32 开发板引脚布局和技术规格

&#x1f517; 快速链接ESP32 Development Boards, Sensors, Tools, Projects and More https://megma.ma/wp-content/uploads/2021/08/Wemos-ESP32-Lolin32-Board-BOOK-ENGLISH.pdf WEMOS LOLIN32 Development Board Details, Pinout, Specs WEMOS LOLIN32 Development Board …

mysql中的group by用法详解

MySQL中的GROUP BY是数据聚合分析的核心功能&#xff0c;主要用于将结果集按指定列分组&#xff0c;并结合聚合函数进行统计计算。以下从基本语法到高级用法进行详细解析&#xff1a; 一、基本语法与核心功能 SELECT 分组列, 聚合函数(计算列) FROM 表名 [WHERE 条件] GROUP B…