Java 使用构建器模式和JVM与Guice理解不变性

Java 使用构建器模式和JVM与Guice理解不变性,java,guice,builder,cucumber-jvm,Java,Guice,Builder,Cucumber Jvm,我在测试自动化项目中使用了cucumberjvm和cucumberguice。我有一个带生成器模式的POJO: class Book { String title; String author; String date; // builder, getter, setter } 然后,在cucumber测试中,我需要在两个步骤中共享Book对象的状态: class BookSteps { @Inject Book book; void firstStep() {

我在测试自动化项目中使用了
cucumberjvm
cucumberguice
。我有一个带生成器模式的POJO:

class Book {
  String title;
  String author;
  String date;
  // builder, getter, setter
}
然后,在cucumber测试中,我需要在两个步骤中共享
Book
对象的状态:

class BookSteps {

  @Inject
  Book book;

  void firstStep() {
    buildBook();
  }

  void secondStep() {
    buildBook().setDate("2019-09-04");
  }

  Book buildBook() {
    return book = Book().BookBuilder().title("Foo").author("Bar").build();
  }

}

因此,正如我正确理解构建器模式一样,它创建了一个
book
的不可变对象。但是,为什么我可以在
secondStep()
方法中通过调用
setDate()
并最终修改它来修改它的状态呢?

您可以修改状态,因为生成器模式没有正确实现。在生成器模式中:

class Book {
  String title;
  String author;
  String date;
  // builder, getter, setter
}
  • 在您的类中不提供变体(或设置器)。设置类属性的唯一方法是通过生成器。只能通过生成器构造函数或生成器的mutator方法设置属性。通常,对于必填字段,可以通过生成器构造函数初始化它们,然后使用生成器setter方法设置其他可选属性
因此,使用builder模式的Book类应如下所示:

    public class Book {
    private String title;
    private String author;
    private String date;

    private Book(Builder builder) {
        title = builder.title;
        author = builder.author;
        date = builder.date;
    }

    public String getTitle() {
        return title;
    }

    public String getAuthor() {
        return author;
    }

    public String getDate() {
        return date;
    }

    public static final class Builder {
        private String title;
        private String author;
        private String date;

        public Builder() {
        }

        public Builder title(String val) {
            title = val;
            return this;
        }

        public Builder author(String val) {
            author = val;
            return this;
        }

        public Builder date(String val) {
            date = val;
            return this;
        }

        public Book build() {
            return new Book(this);
        }
    }
}
下面是测试类:

 public class TestBookBuilder {
    public static void main(String[] args) {
        Book book = new Book.Builder().title("Book title").author("Book Author").date("25-01-2020").build();
    }
}
现在Book类的实例是不可变的


希望有帮助。

Builder并不能保证一个不可变的对象,它只是让构建实例变得有些方便<代码>书籍是可变的-将属性标记为final(然后修复编译错误)。这是对不可变性的一个很好的描述: