Builder模式:用我创建出来的对象,丈母娘不收彩礼钱!

在工作以后,我接触到的创建对象填充属性都是链式编程,builder创建模式。我以前不是很理解为啥非得用这种链式编程。今天想好好絮叨一下,用构建者模式创建管理对象的好处。当你用了以后你会惊叹:啊!真香!

前言

本文将用最简单的方式向大家介绍构建者模式极其使用方式。本文将融合工程实战项目进行讲解。

TOC

何为构建者模式

首先我们看一下官网对这个概念的解释:

网址:《建造者模式》

建造者模式

建造者模式是一种创建型设计模式,它允许你创建复杂对象的步骤与表示方式相分离。

建造者模式是一种创建型设计模式,它的主要目的是将一个复杂对象的构建过程与其表示相分离,从而可以创建具有不同表示形式的对象。

抽取重点:将一个复杂对象的构建过程与其表示相分离

那这里说的复杂对象的构建过程具体是什么意思?有多复杂?让我们用第一性原理剖析。

java 复制代码
package com.linghu.builder.old;
/** 传统构造器模式 */
public class Book {
    private String title;
    private String author;
    private int pages;

    public Book(String title, String author, int pages) {
        this.title = title;
        this.author = author;
        this.pages = pages;
    }

    public Book() {
    }

    public Book(String linghu) {
        this.author=linghu;
    }

    @Override
    public String toString() {
        return "Book{" +
                "title='" + title + '\'' +
                ", author='" + author + '\'' +
                ", pages=" + pages +
                '}';
    }
}

上面这个对象就是复杂对象的构建方式,当我们去new的时候你就会发现有多复杂了。

当我们创建对象传递一个参数的时候:

java 复制代码
 Book book = new Book("linghu");

你就需要在Book类里创建含一个参数的构造器:

java 复制代码
  public Book(String linghu) {
        this.author=linghu;
    }

当我们创建两个参数的构造器的时候:

java 复制代码
 Book book1 = new Book("<java>", "linghu");

你就需要在Book类里创建含两个参数的构造器:

java 复制代码
public Book(String title, String author) {
        this.title = title;
        this.author = author;
    }

当我们创建三个参数的构造器的时候:

java 复制代码
    Book book1 = new Book("<java>", "linghu", 100);

你就需要在Book类里创建含三个参数的构造器:

java 复制代码
public Book(String title, String author, int pages) {
        this.title = title;
        this.author = author;
        this.pages = pages;
    }

有没有发现这很复杂???!

那有没有更灵活的创建对象方式?当然有的,用Builder注解!

Builder注解快速入门

我们直接在实体类对象加一个注解 @Builder 就可以了:

java 复制代码
/** 构建者模式 */
@Builder
public class Book {
    private String title;
    private String author;
    private int pages;

    @Override
    public String toString() {
        return "Book{" +
                "title='" + title + '\'' +
                ", author='" + author + '\'' +
                ", pages=" + pages +
                '}';
    }
}

那接下来怎么新建对象呢?

java 复制代码
Book book = Book.builder()
                .title("<java>")
                .author("linghu")
                .pages(100)
                .build();
        System.out.println(book.toString());

在这里我们惊讶的发现,我们只需要用一个Builder注解就可以不用再像原来那样创建多余的构造函数了。你甚至都不用创建什么无参构造器、有参构造器。你只要builder()调用一下,往里面丝滑地传入参数就可以了。如果你不用上面这种builder创建上面的对象,用传统的方式,那上面这个过程就是这样的:

java 复制代码
Book book = new Book();
book.setAuthor("linghu");
book.setTitle("<java>");
book.setPages(100);
System.out.println(book.toString());

有没有发现这种set属性写出来很丑?

丑是一个问题,你还要在原有的 Book类里添加 setter 和 getter 方法!

Builder构造模式的原理

既然上面介绍了用法和好处,接下来直接用代码自定义一个Builder探寻背后的秘密。

自定义一个Builder:

java 复制代码
package com.linghu.builder.doing;



/** 自定义builder模式 */
public class Book {
    private String title;
    private String author;
    private int pages;

    public Book(String title, String author, int pages) {
        this.title = title;
        this.author = author;
        this.pages = pages;
    }
    public static BookBuilder builder() {
        return new BookBuilder();
    }
    /** 构建者类,提供了title()、author()和pages()方法,用于设置Book对象的属性 */
   public static class BookBuilder {
       private String title;
       private String author;
       private int pages;

       public BookBuilder() {
       }

       public BookBuilder title(String title) {
           this.title = title;
           return this;
       }

       public BookBuilder author(String author) {
           this.author = author;
           return this;
       }

       public BookBuilder pages(int pages) {
           this.pages = pages;
           return this;
       }
       /**通过调用.build()方法,将所有设置的属性整合到一个新的Book对象中。*/
       public Book build(){
           return new Book(title, author, pages);
       }

       @Override
       public String toString() {
           return "BookBuilder{" +
                   "title='" + title + '\'' +
                   ", author='" + author + '\'' +
                   ", pages=" + pages +
                   '}';
       }
   }

    @Override
    public String toString() {
        return "Book{" +
                "title='" + title + '\'' +
                ", author='" + author + '\'' +
                ", pages=" + pages +
                '}';
    }
}

再创建对象的时候,首先调用了 builder方法返回一个 BookBuilder的对象:

java 复制代码
public static BookBuilder builder() {
        return new BookBuilder();
    }

这个 BookBuilder是我们创建的一个静态内部类:

java 复制代码
 /** 构建者类,提供了title()、author()和pages()方法,用于设置Book对象的属性 */
   public static class BookBuilder {
       private String title;
       private String author;
       private int pages;

       public BookBuilder() {
       }

       public BookBuilder title(String title) {
           this.title = title;
           return this;
       }

       public BookBuilder author(String author) {
           this.author = author;
           return this;
       }

       public BookBuilder pages(int pages) {
           this.pages = pages;
           return this;
       }

这个类里面有三个方法,这三个方法帮助我们完成了属性 title、author、pages的填充。

当我们调用 build方法的时候,就会通过链式传递这三个属性的方法:

java 复制代码
/**通过调用.build()方法,将所有设置的属性整合到一个新的Book对象中。*/
       public Book build(){
           return new Book(title, author, pages);
       }

我们再调用builder的全过程如下:

java 复制代码
Book book = Book.builder()
               .title("<java>")
               .author("linghu")
               .pages(100)
               .build();

结尾

ok,上面介绍了builder模式的使用与原理,也介绍了建造者模式的这种应用,以及链式编程的好处。大家可以再工作中多用这种可读性强的方法。

相关推荐
JustHappy2 小时前
古法编程秘籍(二):什么是代码模块化?别背概念,把房间收拾明白就够了
前端·后端
小江的记录本2 小时前
【JVM虚拟机】堆内存分代模型:年轻代(Eden+Survivor)、老年代、元空间Metaspace(附《思维导图》+《面试高频考点清单》)
java·前端·jvm·后端·python·spring·面试
IT_陈寒6 小时前
Python闭包里藏的这个坑,差点让我加班到凌晨
前端·人工智能·后端
IT_陈寒6 小时前
Java注解空指针?这个坑我踩得莫名其妙
前端·人工智能·后端
土狗TuGou6 小时前
SQL内功笔记 · 第8篇:事务的四大特性与隔离级别
数据库·笔记·后端·sql·mysql·oracle
ZengLiangYi6 小时前
React Query + REST API 最佳实践
javascript·后端·react.js
星浩AI6 小时前
项目实战:合同智能审批 · LangGraph + HITL 人机协同方案 [有源码]
后端·langchain·agent
JavaGuide6 小时前
Codex 接入第三方模型 DeepSeek、GLM、Kimi 教程:CC-Switch 和 Codex++ 两种方案对比
后端·ai编程
ZengLiangYi7 小时前
Fastify 加 Electron:把 Web 服务嵌进桌面应用
前端·javascript·后端
李白你好7 小时前
页面资产梳理 · 技术指纹识别 · Spring 端点探测
java·后端·spring