我有两种来自上游的有效负载:PayloadA
或PayloadB
。在PayloadA
和PayloadB
之间有一些公共字段,因此我用这些公共字段创建了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
类(必须是抽象类吗?),在其中我具有PayloadA
和PayloadB
的所有公共字段,因此我还必须以某种方式设置这些字段,并且我不确定如何使用以下课程:public abstract class Payload {
private long createTimestamp;
private String partition;
private String key;
// some other fields here
// getters and setters here
}
题:
现在让我们说,如果我们从上游获取
PayloadB
,那么我希望key
类中的Payload
字段在所有小写形式中以及如果我们获得type类中PayloadB
的值>从上游开始,那么我希望键为PayloadA
。另外,如果我们从上游获取
world
并且设置了PayloadB
,那么我希望clientId
是partition
;如果我们从上游获取15
,并且如果设置了PayloadA
,那么我希望是clientId
,但是如果未设置并且partition
在那,那么我希望15
是langId
。我还想设置
partition
,在构建有效负载对象后必须执行的操作。因此,例如,我已经构建了PayloadA对象,并将其传递给其他一些类,在那里我需要在PayloadA对象上设置createTimestamp值。不知道该怎么做?我是否必须克隆某些东西?如何在构建器模式中使用
17
类?我将获得两个不同的有效负载,并且它们中几乎没有什么共同之处,因此我将这些共同的领域在抽象类中分开了。我应该在大型构建器模式类中包含所有内容,还是应该在多个构建器模式中扩展某些内容?
最佳答案
我不会将builder
实例传递给PayloadX
构造函数。将值作为单独的构造函数参数传递或调用设置器。
您可以定义Payload.Builder
来保存PayloadA
和PayloadB
的公共字段。此类将是一个抽象类,声明一个抽象的build
方法。PayloadA.Builder
和PayloadB.Builder
将扩展Payload.Builder
,实现build
方法。
在此build
方法中,您将实现创建和设置PayloadX
字段所需的任何自定义逻辑。
似乎您想使您的类不可变(顺便提一下applicationPayload
)。在这种情况下,您无法真正“设置”任何东西。您只能产生一个新实例。有很多方法可以做到这一点,例如,您可以实现PayloadX withTimestamp(...)
方法。或者,您可以扩展构建以接受PayloadX
并在那里设置时间戳,从而生成类似new PayloadX.Builder(payloadXInstance).setTimestamp(...).build()
的内容。
关于java - 在构建器模式中使用抽象类?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40990829/