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模式的使用与原理,也介绍了建造者模式的这种应用,以及链式编程的好处。大家可以再工作中多用这种可读性强的方法。

相关推荐
neo_Ggx2330 分钟前
Spring上下文工具类
java·后端·spring
西岭千秋雪_1 小时前
Spring MVC源码分析の请求处理流程
java·后端·spring·mvc·springboot
web147862107231 小时前
Spring Framework 中文官方文档
java·后端·spring
Pitayafruit1 小时前
【📕分布式锁通关指南 07】源码剖析redisson利用看门狗机制异步维持客户端锁
redis·分布式·后端
小菜不菜_xc1 小时前
Spring Boot + MyBatis-Plus 最全配置指南,让你的项目更高效!
java·后端·spring
uhakadotcom1 小时前
阿里云PAI:一站式机器学习平台
后端·面试·github
Matrix702 小时前
Scala编程_数组、列表、元组、集合与映射
开发语言·后端·scala
uhakadotcom2 小时前
阿里云可观测监控Prometheus版:简化监控,提升效率
后端·面试·github
37手游后端团队2 小时前
聊聊提示词注入攻击那些事
人工智能·后端·程序员
Asthenia04122 小时前
从实习生“777惨案”聊起:上生产环境部署 Spring Boot Docker 的正确姿势
后端