繁体   English   中英

在构建器模式中使用抽象类?

[英]Usage of abstract class in the builder pattern?

我有两种类型的有效负载来自上游: PayloadAPayloadB PayloadAPayloadB之间有一些公共字段,因此我使用这些公共字段创建了Payload类,其余的我为每个有效负载创建了两个构建器类。

以下是PayloadA的构建器类:

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的类:

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
}

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

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

  // getters and setters here
}

题:

  • 现在假设如果我们从上游获取PayloadB ,那么我希望Payload类中的key字段在所有小写字母下都是PayloadB类中type的值,如果我们从上游获取PayloadA ,那么我希望key是world
  • 而且如果我们从上游获取PayloadB并且设置了clientId ,那么我希望partition15 ;如果我们从上游获取PayloadA ,并且如果设置了clientId ,那么我希望partition15但是如果未设置,并且langId在那,那么我希望partition17
  • 我还想设置createTimestamp ,这是在构建Payload对象之后要做的。 因此,例如,我已经构建了PayloadA对象,它将被传递到其他类,在那里我需要在PayloadA对象上设置createTimestamp值。 不知道该怎么做? 我是否必须克隆某些东西?

如何在构建器模式中使用Payload类? 我将获得两个不同的有效负载,并且它们中几乎没有什么共同之处,因此我将这些共同的领域划分为一个抽象类。

我应该在大型构建器模式类中包含所有内容,还是应该在多个构建器模式中扩展某些内容?

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM