Java实现建造者模式和源码中的应用

server/2025/1/16 3:48:22/

🎯 设计模式专栏,持续更新中, 欢迎订阅:JAVA实现设计模式
🛠️ 希望小伙伴们一键三连,有问题私信都会回复,或者在评论区直接发言

Java实现建造者模式(Builder Pattern)

文章目录

  • Java实现建造者模式(Builder Pattern)
    • 案例:汉堡制作
    • 建造者模式的核心角色
    • 代码实现:汉堡制作 🍔
      • 内部类实现:
        • Step 1:产品类 Burger
        • Step 2:指挥者 Director
        • Step 3:客户端代码
        • 结果
        • 总结
      • 抽象类实现
        • Step 1:产品类 Burger
        • Step 2:抽象的 Builder 类
        • Step 3:具体的 Builder 类
        • Step 4:指挥者 Director
        • Step 5:客户端代码
        • 输出结果
        • 总结:使用抽象类的优点
    • 源码中的应用
      • 1. `StringBuilder` 和 `StringBuffer`
      • `2.java.util.stream.Stream.Builder`
      • 3.Lombok 中的 `@Builder` 注解
        • 示例:使用 `@Builder` 注解
    • 总结

建造者模式(Builder Pattern)是一种创建型设计模式,主要用于分步骤构建复杂对象。与工厂模式不同的是,建造者模式允许你逐步地构造对象,并且不同的步骤可以有不同的实现,最终组合成一个复杂的对象。

这个模式尤其适合那些需要在多个步骤中配置或构造对象的场景,例如建造房子、配置计算机、制作汉堡🍔等。而且它可以让代码更加清晰灵活,因为你可以通过不同的建造者来实现对象的不同变体。

案例:汉堡制作

假设我们有一个汉堡店,他们提供定制汉堡🍔。顾客可以选择面包类型、肉类、蔬菜、酱料等。每个汉堡可以有不同的组合,因此我们使用建造者模式来简化这个复杂的对象创建过程。

建造者模式的核心角色

  1. Builder(建造者接口/抽象类):定义创建产品对象的各个步骤的接口。
  2. ConcreteBuilder(具体建造者):实现Builder接口,提供步骤的具体实现。
  3. Director(指挥者):负责调用建造步骤,指导建造过程。
  4. Product(产品):最终要创建的复杂对象。

代码实现:汉堡制作 🍔

内部类实现:

Step 1:产品类 Burger
java">// 产品类:Burger
public class Burger {private String bun;       // 面包private String patty;     // 肉饼private String sauce;     // 酱料private String vegetables; // 蔬菜// 私有化构造函数,防止外部直接实例化private Burger() {}// 内部静态Builder类public static class Builder {private String bun;private String patty;private String sauce;private String vegetables;// 构建面包类型public Builder setBun(String bun) {this.bun = bun;return this;}// 构建肉饼类型public Builder setPatty(String patty) {this.patty = patty;return this;}// 构建酱料类型public Builder setSauce(String sauce) {this.sauce = sauce;return this;}// 构建蔬菜种类public Builder setVegetables(String vegetables) {this.vegetables = vegetables;return this;}// 最终构建出一个完整的Burger对象public Burger build() {Burger burger = new Burger();burger.bun = this.bun;burger.patty = this.patty;burger.sauce = this.sauce;burger.vegetables = this.vegetables;return burger;}}// 打印出汉堡的详细信息@Overridepublic String toString() {return "Burger with " + bun + ", " + patty + ", " + sauce + ", " + vegetables;}
}
Step 2:指挥者 Director
java">// 指挥者:负责指导汉堡的制作过程
public class Chef {public Burger makeCheeseburger() {return new Burger.Builder().setBun("Sesame Bun")     // 芝麻面包.setPatty("Beef Patty")   // 牛肉饼.setSauce("Cheese Sauce") // 芝士酱.setVegetables("Lettuce") // 生菜.build();}public Burger makeVeganBurger() {return new Burger.Builder().setBun("Whole Grain Bun") // 全麦面包.setPatty("Vegan Patty")   // 素食饼.setSauce("Mustard Sauce") // 芥末酱.setVegetables("Tomato, Lettuce") // 番茄和生菜.build();}
}
Step 3:客户端代码
java">public class Main {public static void main(String[] args) {Chef chef = new Chef();// 制作一个芝士汉堡Burger cheeseburger = chef.makeCheeseburger();System.out.println(cheeseburger);// 制作一个素食汉堡Burger veganBurger = chef.makeVeganBurger();System.out.println(veganBurger);}
}
结果

当运行这段代码时,输出如下:

Burger with Sesame Bun, Beef Patty, Cheese Sauce, Lettuce
Burger with Whole Grain Bun, Vegan Patty, Mustard Sauce, Tomato, Lettuce
总结

🥷💻 在这个例子中,我们用建造者模式解决了汉堡制作的复杂性:

  1. 可扩展性:我们可以轻松地添加新步骤(比如加奶酪),或添加新的汉堡类型。
  2. 清晰性:使用链式调用方式构建对象,每一步都是明确的。
  3. 灵活性:不同的指挥者可以决定如何组合不同的步骤,产生不同的汉堡变种。

建造者模式非常适合处理需要多步骤配置的复杂对象创建需求,尤其是在需要灵活、可扩展的情况下。💡

抽象类实现

当你有多个复杂对象的构造方式类似,但是具体的构造细节不同,这时可以使用抽象类。抽象类提供一个统一的接口,并允许不同的具体实现类来实现各自的构建步骤。

例如,如果你有多个不同类型的“汉堡”或其他类型的复杂对象,这些对象有相似的结构,但具体的细节不同,那么抽象类就能发挥作用。抽象类提供了基础构建逻辑,而具体的子类负责实现细节

多个复杂对象共享部分构造逻辑:抽象类可以提供共享的构建步骤,具体的构建步骤由子类实现。

强制规范步骤:抽象类可以定义必须实现的方法,这样确保子类都能实现这些步骤。

减少重复代码:如果不同对象之间的构建步骤大部分相同,使用抽象类可以避免重复代码。

Step 1:产品类 Burger
java">// 产品类:汉堡
public class Burger {private String bun;private String patty;private String sauce;private String vegetables;// 各个字段的设置方法public void setBun(String bun) {this.bun = bun;}public void setPatty(String patty) {this.patty = patty;}public void setSauce(String sauce) {this.sauce = sauce;}public void setVegetables(String vegetables) {this.vegetables = vegetables;}// 输出汉堡详细信息@Overridepublic String toString() {return "Burger with " + bun + ", " + patty + ", " + sauce + ", " + vegetables;}
}
Step 2:抽象的 Builder 类
java">// 抽象建造者:定义基本的构建步骤
public abstract class BurgerBuilder {protected Burger burger;// 创建新的汉堡public void createNewBurger() {burger = new Burger();}// 具体的构建步骤,由子类实现public abstract void buildBun();public abstract void buildPatty();public abstract void buildSauce();public abstract void buildVegetables();// 返回最终构建的产品public Burger getBurger() {return burger;}
}
Step 3:具体的 Builder 类
java">// 具体的芝士汉堡建造者
public class CheeseburgerBuilder extends BurgerBuilder {@Overridepublic void buildBun() {burger.setBun("Sesame Bun");}@Overridepublic void buildPatty() {burger.setPatty("Beef Patty");}@Overridepublic void buildSauce() {burger.setSauce("Cheese Sauce");}@Overridepublic void buildVegetables() {burger.setVegetables("Lettuce");}
}// 具体的素食汉堡建造者
public class VeganBurgerBuilder extends BurgerBuilder {@Overridepublic void buildBun() {burger.setBun("Whole Grain Bun");}@Overridepublic void buildPatty() {burger.setPatty("Vegan Patty");}@Overridepublic void buildSauce() {burger.setSauce("Mustard Sauce");}@Overridepublic void buildVegetables() {burger.setVegetables("Tomato, Lettuce");}
}
Step 4:指挥者 Director
java">// 指挥者:负责调用建造者的构建步骤
public class Chef {private BurgerBuilder burgerBuilder;// 设置当前的建造者public void setBurgerBuilder(BurgerBuilder burgerBuilder) {this.burgerBuilder = burgerBuilder;}// 返回最终构建的汉堡public Burger getBurger() {return burgerBuilder.getBurger();}// 按步骤构建汉堡public void constructBurger() {burgerBuilder.createNewBurger();burgerBuilder.buildBun();burgerBuilder.buildPatty();burgerBuilder.buildSauce();burgerBuilder.buildVegetables();}
}
Step 5:客户端代码
java">public class Main {public static void main(String[] args) {Chef chef = new Chef();// 制作芝士汉堡BurgerBuilder cheeseburgerBuilder = new CheeseburgerBuilder();chef.setBurgerBuilder(cheeseburgerBuilder);chef.constructBurger();Burger cheeseburger = chef.getBurger();System.out.println(cheeseburger);// 制作素食汉堡BurgerBuilder veganBurgerBuilder = new VeganBurgerBuilder();chef.setBurgerBuilder(veganBurgerBuilder);chef.constructBurger();Burger veganBurger = chef.getBurger();System.out.println(veganBurger);}
}
输出结果
Burger with Sesame Bun, Beef Patty, Cheese Sauce, Lettuce
Burger with Whole Grain Bun, Vegan Patty, Mustard Sauce, Tomato, Lettuce
总结:使用抽象类的优点
  1. 扩展性更强:如果要添加新的汉堡种类(比如鸡肉汉堡),只需要继承抽象的 BurgerBuilder 类并实现它的具体方法,不需要修改已有的代码。
  2. 代码复用:公共逻辑可以在抽象类中实现,减少子类的代码重复。
  3. 更灵活的设计:通过定义抽象的步骤,强制每个子类实现各自的步骤,实现了结构的统一性和逻辑的灵活性。

💡 在这种情况下,抽象类为不同类型的汉堡提供了一个标准化的构建流程,同时允许具体的实现类定义各自的细节,使得代码更具灵活性和可维护性。

源码中的应用

Java 标准库中,建造者模式(Builder Pattern)被广泛应用于许多类库和框架,尤其是在创建复杂对象时。这个模式的使用可以大大提高代码的可读性、可维护性,并且能够简化对象的创建过程

以下是一些经典的 Java 源码应用了建造者模式的例子

1. StringBuilderStringBuffer

StringBuilderStringBuffer 是 Java 中经常使用的用于操作字符串的类,它们可以逐步构建一个字符串,类似于建造者模式

java">StringBuilder sb = new StringBuilder();
sb.append("Hello").append(" ").append("World").append("!");System.out.println(sb.toString());  // 输出 "Hello World!"

javautilstreamStreamBuilder_369">2.java.util.stream.Stream.Builder

Java 8 引入了 Stream API,Stream.Builder 是一种典型的建造者模式的应用,用于构建 Stream 对象。

java">Stream.Builder<String> builder = Stream.builder();
builder.add("one").add("two").add("three");Stream<String> stream = builder.build();  // 创建流
stream.forEach(System.out::println);

3.Lombok 中的 @Builder 注解

示例:使用 @Builder 注解

假设我们有一个 Person 类,包含姓名、年龄和地址等字段。我们可以使用 @Builder 注解来简化对象创建。

java">import lombok.Builder;
import lombok.ToString;@Builder
@ToString
public class Person {private String name;private int age;private String address;
}

通过 @Builder 注解,Lombok 会自动为我们生成一个建造者模式类。接下来我们就可以像这样使用:

java">public class Main {public static void main(String[] args) {Person person = Person.builder().name("Alice").age(25).address("123 Main St").build();System.out.println(person);}
}

#####*Lombok 自动生成的代码

Lombok 的 @Builder 实际上为我们生成了一个内部的静态 Builder 类,它的结构与我们手动实现的建造者模式非常相似。以 Person 类为例,Lombok 生成的 Builder 类大概是这样:

java">public class Person {private String name;private int age;private String address;// 私有构造函数,防止直接创建对象private Person(PersonBuilder builder) {this.name = builder.name;this.age = builder.age;this.address = builder.address;}public static PersonBuilder builder() {return new PersonBuilder();}// 静态的内部类 PersonBuilderpublic static class PersonBuilder {private String name;private int age;private String address;public PersonBuilder name(String name) {this.name = name;return this;}public PersonBuilder age(int age) {this.age = age;return this;}public PersonBuilder address(String address) {this.address = address;return this;}public Person build() {return new Person(this);}}@Overridepublic String toString() {return "Person(name=" + this.name + ", age=" + this.age + ", address=" + this.address + ")";}
}

总结

这些 Java 标准库中的类展示了建造者模式在实际开发中的广泛应用。建造者模式通过分步骤地构建复杂对象,提高了代码的灵活性可读性,避免了冗长的构造函数调用。这使得代码更具扩展性,并且适合于那些对象创建过程中需要多步骤、多参数的场景。


http://www.ppmy.cn/server/117354.html

相关文章

【机器学习】7 ——k近邻算法

机器学习7——k近邻 输入&#xff1a;实例的特征向量 输出&#xff1a;类别 懒惰学习&#xff08;lazy learning&#xff09;的代表算法 文章目录 机器学习7——k近邻1.k近邻2.模型——距离&#xff0c;k&#xff0c;分类规则2.1距离——相似程度的反映2.2 k值分类规则 算法实…

ModbusTCP/RTU转Ethernet/IP(CIP)-Modbus设备与罗克韦尔AB的PLC之间通讯

IGT-DSER智能网关模块支持西门子、三菱、欧姆龙、罗克韦尔AB等各种品牌的PLC之间通讯&#xff0c;同时也支持PLC与Modbus协议的工业机器人、智能仪表、变频器等设备通讯。网关有多个网口、串口&#xff0c;也可选择WIFI无线通讯。无需PLC内编程开发&#xff0c;只要在IGT-DSER智…

基于微信小程序的图书馆预约占座系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 基于微信小程序JavaSpringBootVueMySQL的图…

【Linux 从基础到进阶】自动化备份与恢复策略

自动化备份与恢复策略 在 Linux 运维中,数据的安全性至关重要,自动化备份与恢复策略是保障系统和数据安全的核心环节。无论是系统配置文件、用户数据、数据库还是应用程序日志,备份和恢复都能为系统灾难恢复、数据丢失等突发情况提供可靠的解决方案。 本文将介绍如何在 Ce…

关于easyadmin权限配置

1&#xff0c;在index.html 设置需要权限的放方法 <div class"layuimini-container"> <div class"layuimini-main"> <table id"currentTable" class"layui-table layui-hide" data-auth-add"{:auth(enterprise/a…

Jetpack PDF库:解锁Android应用中的PDF功能

Jetpack PDF库&#xff1a;解锁Android应用中的PDF功能 在 Android 开发中&#xff0c;加载 PDF 文件是一个比较常见的需求&#xff0c;但就是这么一个比较常见的功能&#xff0c;原生并没有提供一个比较好的方案&#xff0c;而隔壁 IOS 中实现却是很方便的。。。 下面是当前…

53.9k star 提升命令行效率的模糊搜索神器--fzf

fzf简介 作为Linux/Unix命令行的重度用户,你是否还在使用繁琐的管道命令与复杂选项组合来过滤文件和数据?其实我们有一个更简单高效的选择 - fzf。 fzf是一个开源的通用模糊搜索工具,可以大幅度提升命令行的使用体验。它的查询运行速度极快,支持预览选中的文件内容,还能与各…

【机器学习-监督学习】集成学习与梯度提升决策树

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈Python机器学习 ⌋ ⌋ ⌋ 机器学习是一门人工智能的分支学科&#xff0c;通过算法和模型让计算机从数据中学习&#xff0c;进行模型训练和优化&#xff0c;做出预测、分类和决策支持。Python成为机器学习的首选语言&#xff0c;…