生成泛型类型的构建器模式的自动化生成

huangapple go评论73阅读模式
英文:

Automatic generation of builder pattern that boxes generic type

问题

一条命令由Builder实例化,当设置值时,将其包装在一个Undefined对象中(然后在execute方法中使用该对象,仅在已设置newTitle时设置书名)。

命令类:

public class UpdateBookCommand {
  Book book;
  Undefined<String> newTitle;

  public Book execute(){
    if(newTitle.isDefined())
      this.book.setTitle(this.newTitle.get());
    return this.book;
  }

  public static class Builder {
    Book book;
    Undefined<String> newTitle = Undefined.instance();

    public Builder(Book book) {
      this.book=book;
    }

    public Builder newTitle(String newTitle){
      this.newTitle=Undefined.of(newTitle);
    }

    public UpdateBookCommand build() {
      UpdateBookCommand command = new UpdateBookCommand();
      command.newTitle=this.newTitle;
      return command;
    }
  }
}

这个模式运行良好,我打算在所有命令中都使用它,但需要大量样板代码。我想使用Lombok的@Builder、FreeBuilder或任何其他代码生成工具自动生成这些代码,但我无法找到如何自动生成Undefined包装器的方法。

这两个工具都会生成:

public Builder newTitle(Undefined<String> newTitle)){
  this.newTitle=newTitle;
}

而不是:

public Builder newTitle(String newTitle){
  this.newTitle=Undefined.of(newTitle);
}

有没有办法更改@Builder@Freebuilder注释生成的代码模板,或者有其他工具可以替代吗?

英文:

A command is instantiated by a Builder, that, when setting values, wraps them in an Undefined object (this is then used in the execute method to set the book's title only if the newTitle has been set).

The command class:

public class UpdateBookCommand {
  Book book;
  Undefined&lt;String&gt; newTitle;

  public Book execute(){
    if(newTitle.isDefined())
      this.book.setTitle(this.newTitle.get());
    return this.book;
  }

  public static class Builder {
    Book book;
    Undefined&lt;String&gt; newTitle = Undefined.instance();

    public Builder(Book book) {
      this.book=book;
    }

    public Builder newTitle(String newTitle){
      this.newTitle=Undefined.of(newTitle);
    }
    
    public UpdateBookCommand build() {
      UpdateBookCommand command = new UpdateBookCommand();
      command.newTitle=this.newTitle;
      return command;
    }
  }
}

This pattern works well and I intend to use it for all my commands, but requires a lot of boilerplate code that I would like to automatically generate using Lombok @Builder or FreeBuilder or any other code generation tool, but I cannot find how to automatically generate the Undefined wrapper.

Both tools would generate

public Builder newTitle(Undefined&lt;String&gt; newTitle)){
  this.newTitle=newTitle;
}

instead of

public Builder newTitle(String newTitle){
  this.newTitle=Undefined.of(newTitle);
}

Is there a way to change the template of the code generated by the @Builder or @Freebuilder annotations, or any other tool I could use instead?

答案1

得分: 1

你可以使用 Lombok 的 @Builder,并自定义不符合你需求的部分。在生成器类中已存在的任何内容都将被 Lombok 静默忽略,其余部分将按通常方式生成。

在你的示例中,代码如下:

@Builder
public class UpdateBookCommand {
  Book book;
  Undefined<String> newTitle;

  public static class UpdateBookCommandBuilder {
    public Builder newTitle(String newTitle) {
      this.newTitle = Undefined.of(newTitle);
    }
  }
  // 这里是你的方法。
}
英文:

You can use Lombok's @Builder and customize the parts that don't fit your needs. Anything that already exists in the builder class will be silently ignored by Lombok, and everything else will be generated as usual.

In your example, this looks as follows:

@Builder
public class UpdateBookCommand {
  Book book;
  Undefined&lt;String&gt; newTitle;

  public static class UpdateBookCommandBuilder {
    public Builder newTitle(String newTitle) {
      this.newTitle=Undefined.of(newTitle);
    }
  }
  // Your methods here.
}

huangapple
  • 本文由 发表于 2020年9月16日 12:09:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/63912996.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定