在构建器模式中使用 abstract class?

Usage of abstract class in the builder pattern?

我有两种来自上游的负载:PayloadAPayloadBPayloadAPayloadB 之间有一些公共字段,所以我用这些公共字段创建了 Payload class,其余的我为每个有效负载创建了两个构建器 class .

下面是 PayloadA 的生成器 class:

public final class PayloadA {
  private final String clientId;
  private final String langid;
  private final String deviceId;
  private final Map<String, String> applicationPayload;

  private PayloadA(Builder builder) {
    this.clientId = builder.clientId;
    this.langid = builder.langid;
    this.deviceId = builder.deviceId;
    this.applicationPayload = builder.applicationPayload.build();
  }

  public static class Builder {
    protected final String deviceId;
    protected String clientId;
    protected String langid;
    protected ImmutableMap.Builder<String, String> applicationPayload = ImmutableMap.builder();

    public Builder(String deviceId) {
      this.deviceId = deviceId;
    }

    public Builder setClientId(String clientId) {
      this.clientId = clientId;
      return this;
    }

    public Builder setLangid(String langid) {
      this.langid = langid;
      return this;
    }

    public Builder setPayload(Map<String, String> payload) {
      this.applicationPayload.putAll(payload);
      return this;
    }

    public PayloadA build() {
      return new PayloadA(this);
    }
  }

    // getters and to string here
}

下面是 PayloadB 的 class:

public final class PayloadB {
  private final String clientid;
  private final String type;
  private final String payId;

  private PayloadB(Builder builder) {
    this.clientid = builder.clientid;
    this.type = builder.type;
    this.payId = builder.payId;
  }

  public static class Builder {
    protected final String type;
    protected String payId;
    protected String clientid;

    public Builder(String type) {
      this.type = type;
    }

    public Builder setPayId(String payId) {
      this.payId = payId;
      return this;
    }

    public Builder setClientId(String clientid) {
      this.clientid = clientid;
      return this;
    }

    public PayloadB build() {
      return new PayloadB(this);
    }
  }

    // getters and to string here
}

现在我创建了另一个 class,它是 Payload class(这必须是抽象的 class?),其中我有所有公共字段对于 PayloadAPayloadB 所以我也必须以某种方式设置这些字段,我不确定如何在下面使用 class:

public abstract class Payload {
  private long createTimestamp;
  private String partition;
  private String key;
  // some other fields here

  // getters and setters here
}

问题:

如何在构建器模式中使用 Payload class?我将得到两个不同的有效载荷,它们之间几乎没有共同点,所以我将它们抽象地分开 class.

我应该使用包含所有内容的大型构建器模式 class 还是扩展某些内容的多个构建器模式?

  • 我不会将 builder 实例传递给 PayloadX 构造函数。要么将值作为单独的构造函数参数传递,要么调用设置器。
  • 您可以定义 Payload.Builder,它包含 PayloadAPayloadB 的公共字段。此 class 将是一个抽象 class 声明一个抽象 build 方法。
  • PayloadA.BuilderPayloadB.Builder 将扩展 Payload.Builder,实现 build 方法。
  • 在这个 build 方法中,您可以实现任何需要创建和设置 PayloadX 字段的自定义逻辑。

您似乎想让 class 不可变(顺便提一下 applicationPayload)。在这种情况下,你真的不能 "set" 任何东西。您只能生成一个新实例。有很多方法可以做到这一点,例如你可以实现 PayloadX withTimestamp(...) 方法。或者您可以扩展您的构建以接受 PayloadX 并在那里设置时间戳,从而导致类似于 new PayloadX.Builder(payloadXInstance).setTimestamp(...).build().