建造者(Builder)模式

白昼怎懂夜的黑 提交于 2020-03-15 09:47:39

建造者模式(Builder Pattern)又称生成器模式,熟悉lombok的朋友应该有印象,lombok有一个注解(Annotation)叫@Builder。

import lombok.Builder;
import lombok.ToString;

@Builder
@ToString
public class Book {
    private Long id;

    private String name;

    private String author;
}

然后是测试类:

public class BuilderTest {
    public static void main(String[] args) {
        Book book = Book.builder().id(1L).name("《西游记》").author("吴承恩").build();
        System.out.println(book);
    }
}

执行打印输出:

Book(id=1, name=《西游记》, author=吴承恩)

我们可以看到main方法构造Book对象的时候,并没有new,而是用Book的builder方法链式调用来构造出来Book对象的。

我们可以去target目录查看编译的class文件,发现Book其实一共有两个class文件:

Book.class

Book$BookBuilder.class

这个BookBuilder就是Book的一个内部类。

我们可以用反编译工具看一下Book类的真实内容:

public class Book
{
  private Long id;
  private String name;
  private String author;
  
  public static class BookBuilder
  {
    private Long id;
    private String name;
    private String author;
    
    public String toString()
    {
      return "Book.BookBuilder(id=" + this.id + ", name=" + this.name + ", author=" + this.author + ")";
    }
    
    public Book build()
    {
      return new Book(this.id, this.name, this.author);
    }
    
    public BookBuilder author(String author)
    {
      this.author = author;return this;
    }
    
    public BookBuilder name(String name)
    {
      this.name = name;return this;
    }
    
    public BookBuilder id(Long id)
    {
      this.id = id;return this;
    }
  }
  
  Book(Long id, String name, String author)
  {
    this.id = id;this.name = name;this.author = author;
  }
  
  public static BookBuilder builder()
  {
    return new BookBuilder();
  }
  
  public String toString()
  {
    return "Book(id=" + this.id + ", name=" + this.name + ", author=" + this.author + ")";
  }
}

这样我们看起来就比较轻松了,大概就能了解到Book的Builder是怎么运作的。这种依赖关系如图所示:

其实这就是Builder(建造者)模式。BookBuilder将对象Book的建造过程抽象出来。而且这个创建Book的过程可以根据不同的方法(或者说不同的构造Book属性方法的调用)构造出不同的对象。

比如:

// 没有author
Book book = Book.builder().id(1L).name("《西游记》").build();
// 没有id
Book book = Book.builder().name("《西游记》").author("吴承恩").build();

当然我们也可以自己编写一个抽象的Builder方法,然后再实现具体的Builder方法。

最后我们可以看到这种方式对于创建对象来说简单方法,隐藏了内部的逻辑实现,比使用setter更加直观。

当然如果对象的属性比较多的时候,如果手动实现就比较麻烦,还好有Lombok这样的插件。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!