Java 在生成器模式中使用抽象类?
我有两种来自上游的有效载荷:要么是Java 在生成器模式中使用抽象类?,java,design-patterns,fluent,builder-pattern,Java,Design Patterns,Fluent,Builder Pattern,我有两种来自上游的有效载荷:要么是PayloadA要么是PayloadB。在PayloadA和PayloadB之间有一些公共字段,所以我用这些公共字段创建了PayloadA类,其余的我为每个有效负载创建了两个构建器类 下面是PayloadA的生成器类: public final class PayloadA { private final String clientId; private final String langid; private final String device
PayloadA
要么是PayloadB
。在PayloadA
和PayloadB
之间有一些公共字段,所以我用这些公共字段创建了PayloadA
类,其余的我为每个有效负载创建了两个构建器类
下面是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
}
现在我创建了另一个类,它是Payload
class(这必须是抽象类吗?),其中我有PayloadA
和PayloadB
的所有公共字段,因此我必须以某种方式设置这些字段,我不确定如何使用下面的类:
public abstract class Payload {
private long createTimestamp;
private String partition;
private String key;
// some other fields here
// getters and setters here
}
问题:
- 现在让我们假设如果我们从上游获得
,那么我希望PayloadB
类中的PayloadB
字段是key
类中所有小写形式的PayloadB
的值,如果我们从上游获得type
,那么我希望key是PayloadA
world
- 而且如果我们从上游获得
,如果设置了PayloadB
,然后我希望clientId
成为partition
如果我们从上游获得15
并且如果PayloadA
被设置,那么我希望clientId
成为partition
,但是如果没有设置并且15
在那里,那么我希望langId
成为partition
17
- 我想设置
,这也是我在构建有效负载对象之后必须做的。例如,我构建了PayloadA对象,它将被传递给其他类,在那里我需要在PayloadA对象上设置CreateTimstamp值。不知道该怎么做?我必须克隆一些东西吗createTimestamp
有效负载类?我将得到两个不同的有效载荷,它们中几乎没有共同点,所以我在一个抽象类中将它们分离出来
我应该在大构建器模式类中使用它的所有内容还是多个构建器模式扩展某些内容?
- 我不会将
builder
实例传递给PayloadX
构造函数。将值作为单个构造函数参数或调用设置器传递
- 您可以定义
Payload.Builder
,它将保存PayloadA
和PayloadB
的公共字段。这个类将是一个抽象类,它声明了一个抽象的build
方法
PayloadA.Builder
和PayloadB.Builder
将扩展PayloadA.Builder
,实现build
方法
- 在这个
build
方法中,您可以实现创建和设置PayloadX
字段所需的任何自定义逻辑
看起来您希望使类不可变(顺便提一下,小心applicationPayload
)。在这种情况下,您无法真正“设置”任何内容。您只能生成一个新实例。有很多方法可以做到这一点,例如,您可以实现PayloadX with timestamp(…)
方法。或者,您可以扩展构建以接受PayloadX
并在那里设置时间戳,从而生成类似于new PayloadX.Builder(payloadXInstance).setTimestamp(…).build()
- 我不会将
builder
实例传递给PayloadX
构造函数。将值作为单个构造函数参数或调用设置器传递
- 您可以定义
Payload.Builder
,它将保存PayloadA
和PayloadB
的公共字段。这个类将是一个抽象类,它声明了一个抽象的build
方法
PayloadA.Builder
和PayloadB.Builder
将扩展PayloadA.Builder
,实现build
方法
- 在这个
build
方法中,您可以实现创建和设置PayloadX
字段所需的任何自定义逻辑
看起来您希望使类不可变(顺便提一下,小心applicationPayload
)。在这种情况下,您无法真正“设置”任何内容。您只能生成一个新实例。有很多方法可以做到这一点,例如,您可以实现PayloadX with timestamp(…)
方法。或者您可以扩展您的构建以接受PayloadX
并在那里设置时间戳,从而生成类似new PayloadX.Builder(payloadXInstance).setTimestamp(…).build()
您能提供一个上述所有建议的示例吗?这将帮助我更好地理解。到目前为止,我对如何使用你的建议感到困惑。@david对不起,这不会超过我准备贡献的时间。你能举一个例子说明你所有的建议吗?这将帮助我更好地理解。到目前为止,我对如何使用您的建议感到困惑。@david我不会,对不起,这超过了我准备贡献的时间。首先,您为什么要使用构建器?看起来代码设计过度了…一般来说,所有这些有效负载都有很多字段。为了使示例更易于理解,我这样做了。好吧,你们之所以引入构建器,是因为有大量的类。您是否已经考虑过在较小的类中进行重构,从而解决问题的根源?目前,你的问题听起来像是一个问题:你问如何在构建器中使用抽象类(这是一个非常罕见的问题),而不是问自己“为什么我最终会出现这样一个奇怪的构造?”嗯,那么我应该如何解决这个问题?你需要PayloadX
?他们是DTO还是BO?它们是否真的包含一些业务逻辑,或者只是一堆getter?发布完整的代码(至少所有的属性)现实吗?首先,为什么要使用构建器?看起来代码设计过度了…一般来说
public abstract class Payload {
private long createTimestamp;
private String partition;
private String key;
// some other fields here
// getters and setters here
}