抽象类在构建器模式中的使用? [英] Usage of abstract class in the builder pattern?
问题描述
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 wantkey
field in thePayload
class to be whatever is the value oftype
inPayloadB
class in all lower case and if we getPayloadA
from upstream, then I want key to beworld
. - And also if we get
PayloadB
from upstream and ifclientId
was set, then I wantpartition
to be15
and if we getPayloadA
from upstream and ifclientId
was set then I wantpartition
to be15
but if it was not set andlangId
was there, then I wantpartition
to be17
. - 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 thePayloadX
constructor. Either pass values as individual constructor arguments or call setters. - You can define
Payload.Builder
which would hold common fields ofPayloadA
andPayloadB
. This class will be an abstract class declaring an abstractbuild
method. PayloadA.Builder
andPayloadB.Builder
will extendPayload.Builder
, implementing thebuild
method.- In this
build
method you implement whatever custom logic you need to create and set the fields of thePayloadX
.
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屋!