抽象类在构建器模式中的使用? [英] Usage of abstract class in the builder pattern?

查看:196
本文介绍了抽象类在构建器模式中的使用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两种来自上游的有效载荷:它是 PayloadA PayloadB 。在 PayloadA PayloadB 之间有一些常见的字段,所以我创建了有效负载类与这些常见的字段和休息我为每个有效负载创建了两个构建器类。



下面是 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;
返回这个;
}

public Builder setLangid(String langid){
this.langid = langid;
返回这个;
}

public Builder setPayload(Map< String,String> payload){
this.applicationPayload.putAll(payload);
返回这个;
}

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

// getter和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;
返回这个;
}

public Builder setClientId(String clientid){
this.clientid = clientid;
返回这个;
}

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

// getter和string here
}

现在我已经创建了另一个类,它是 Payload class(这必须是抽象类吗?),其中有我所有的常见字段对于 PayloadA PayloadB ,所以我必须设置这些字段,不知何故,我不知道如何使用下面类:

  public abstract class Payload {
private long createTimestamp;
private String partition;
private String key;
//其他一些字段

// getter和setter这里
}

问题:




  • 现在让我们说如果我们得到 PayloadB 从上游,然后我想要 Payload 类中的 PayloadB 类中的类型的值,如果我们得到 PayloadA 从上游,然后我想要的密钥是世界

  • 如果我们得到 PayloadB 从上游,如果 clientId 被设置,那么我想要分区 15 ,如果我们从上游获取 PayloadA ,如果 clientId 被设置,然后我想要分区 15 但如果没有设置, langId 在那里,然后我想要分区 17

  • 而且我想设置 createTimestamp 以及我有o在构建一个有效负载对象之后。所以例如我已经建立了PayloadA对象,它将被传递给一些其他类,我需要在PayloadA对象上设置createTimestamp值。不知道该怎么做呢?我必须克隆某些东西吗?



如何使用 Payload 我的建筑师模式?我将获得两个不同的有效载荷,并且在它们中常常有很少的东西,所以常见的领域我将它们分离出来,在一个抽象类中。



我应该有大的构建器模式/ />

解决方案


  • 我不会通过 builder 实例到 PayloadX 构造函数。可以将值作为单独的构造函数参数或调用设置器传递。

  • 您可以定义 Payload.Builder ,它将保存 PayloadA PayloadB 。这个类将是一个抽象类,声明一个抽象的 build 方法。

  • PayloadA.Builder PayloadB.Builder 将扩展 Payload.Builder ,实现 build 方法。

  • 在这个 build 方法中,您可以实现创建和设置 PayloadX



似乎你想让你的课不可变与 applicationPayload 顺便说一下)。在这种情况下,您无法真正设置任何内容。你只能生成一个新的实例。有很多方法可以做到这一点,例如您可以使用Timestamp(...)方法实现 PayloadX。或者您可以扩展您的构建以接受 PayloadX 并在那里设置时间戳,导致类似于新的PayloadX.Builder(payloadXInstance).setTimestamp(...) ).build()


I have two types of payload coming from upstream: It's either PayloadA or PayloadB. There are some common fields between PayloadA and PayloadB so I created Payload class with those common fields and for rest I created two builder class one for each payload.

Below is the builder class for 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
}

Now below is the class for 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
}

Now I have created another class which is Payload class (does this have to be abstract class?) in which I have all the common fields both for PayloadA and PayloadB so I have to set these fields as well somehow and I am not sure how to use below class:

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

  // getters and setters here
}

Question:

  • Now let's say if we get PayloadB from upstream, then I want key field in the Payload class to be whatever is the value of type in PayloadB class in all lower case and if we get PayloadA from upstream, then I want key to be world.
  • And also if we get PayloadB from upstream and if clientId was set, then I want partition to be 15 and if we get PayloadA from upstream and if clientId was set then I want partition to be 15 but if it was not set and langId was there, then I want partition to be 17.
  • And I want to set createTimestamp as well which I have to do after building a Payload object. So for example I have build PayloadA object and it will be passed to some other class and there I need to set createTimestamp value on PayloadA object. Not sure how to do that as well? Do I have to clone something?

How can I use Payload class in my builder pattern? I will get two different payloads and there will be few things common in them so common fields I have separated them out in an abstract class.

Should I have on big builder pattern class with everything in it or multiple builder pattern extending something?

解决方案

  • I won't pass builder instance to the PayloadX constructor. Either pass values as individual constructor arguments or call setters.
  • You can define Payload.Builder which would hold common fields of PayloadA and PayloadB. This class will be an abstract class declaring an abstract build method.
  • PayloadA.Builder and PayloadB.Builder will extend Payload.Builder, implementing the build method.
  • In this build method you implement whatever custom logic you need to create and set the fields of the PayloadX.

It seems like you want to make your class immutable (careful with applicationPayload by the way). In this case you can't really "set" anything. You can only produce a new instance. There are many ways to do this, for instance you can implement PayloadX withTimestamp(...) method. Or you can extend your build to accept PayloadX and set timestamp there, resulting in something like new PayloadX.Builder(payloadXInstance).setTimestamp(...).build().

这篇关于抽象类在构建器模式中的使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆