我有两种来自上游的有效负载:它是PayloadA
或PayloadB
。与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;
// other fields as well
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;
// other fields as well
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 key;
// some other fields are here
// getters and setters here
}
问题:
现在,根据以下代码,我根据传递的内容制作PayloadA
或PayloadB
。
private void run(String name) {
// .. some code here
if (name.equalsIgnoreCase("PayloadA")) {
Payload payload =
new PayloadA.Builder(getDeviceId()).setClientId("someid").setLangid("anotherid")
.setPayload("some map").build();
DataProcessor.getInstance().process(payload);
} else {
Payload payload =
new PayloadB.Builder(getType()).setPayId("someid").setClientId("anotherid").build();
DataProcessor.getInstance().process(payload);
}
}
并使用DataProcessor
process
方法:
private void process(Payload payload) {
// 1) here I need to set createTimestamp and key variables on payload bcoz they are common
// fields.
// 2) Also how can I figure out whether payload is PayloadA or PayloadB here?
}
现在,如何在createTimestamp
方法中设置key
类中的Payload
和process
变量?现在我有一个运行方法,我区分它,但一般来说,我将有一个不同的PayloadA上游代码和PayloadB的不同上游代码,所以根据我们将使用任何一个Payload类。
我也应该在这里有两个不同的建造者或一个大建筑师在做什么吗?
答案 0 :(得分:1)
PayloadA
和PayloadB
可以展开Payload
,如下所示:
public abstract class Payload {
private long createTimestamp;
private String key;
// some other fields are here
// getters and setters here
}
public class PayloadA extends Payload {
//add existing code
}
public class PayloadB extends Payload {
//add existing code
}
private void process(Payload payload) {
//Depending upon the object passed, fields will be set for A or B
payload.setCreateTimestamp(ADD_DATA1);
payload.setKey(ADD_DATA2);
//set other fields
//if(payload instanceof PayloadA) {
//payloadA
//}
}
如何确定有效负载是
PayloadA
还是PayloadB
在process()
内?
您可以使用instanceof
payload
instanceof
PayloadA
来查找,如上所示。但是,一般来说,使用instanceof
检查进行编码并不是一个好主意,所以除非无法避免,否则不要使用它。
我在这里应该有两个不同的建造者还是一个大建筑商 干什么?
根据您提供的代码,字段非常PayloadA
和PayloadB
不同,因此最好保留单独的bean和各自的构建器。
更新:我需要弄清楚它的有效载荷类型和基础 我需要为关键变量设置值吗?
内部setKey()
将在传递给process(Payload payload)
的对象类型上调用(多态,OOP的基本原则之一),即,如果从{{1}传递PayloadA
对象方法,将调用run()
对象上的setKey()
。 总结一下,您根本无需进行PayloadA
检查。根据您的要求,您要在哪里设置密钥,它可能位于instanceof
方法内(如果你有一些其他的依赖关系来生成process()
),或者它可以按照@Roberto的建议完成
答案 1 :(得分:1)
abstract public class Payload {
abstract void setKey();
}
public class PayloadA extends Payload {
//add existing code
void setKey() {
key = "a";
}
}
public class PayloadB extends Payload {
//add existing code
void setKey() {
key = "b";
}
}
private void process(Payload payload) {
//Depending upon the object passed, fields will be set for A or B
payload.setCreateTimestamp(ADD_DATA1);
payload.setKey();
}
修改强>:
这里的想法是任何扩展有效负载的类必须实现setKey()方法,或者本身是抽象的。所以,PayloadA和PayloadB都实现了这个方法。每个类提供不同的实现。
现在假设你做了
PayloadA pa = new PayloadA();
pa.setKey()
正如预期的那样,实际执行的实现将是PayloadA中定义的实现。
现在考虑一下这个案例:
Payload pa = new PayloadA();
pa.setKey()
尽管变量被声明为Payload类型,但变量引用的对象的实际类型是PayloadA,因此setKey()调用是PayloadA中的调用。这称为动态调度,因为调用哪个实现在运行时是已知的,而不是在编译时已知
答案 2 :(得分:0)
public class Payload {
// common fields
private String clientid;
private String key;
private long Timestamp;
// setter and getters
}
public class PayloadA extends Payload implements PayloadStrategy {
// PayloadA specific fields
private String langid;
private String deviceId;
// setters and getters
public static class Builder {
// existing code
}
@Override
public void process() {
System.out.println("PayloadA specific implementation");
}
}
public class PayloadB extends Payload implements PayloadStrategy {
// PayloadA specific fields
private String type;
private String payId;
// setters and getters
public static class Builder {
// existing code
}
@Override
public void process() {
System.out.println("PayloadB specific implementation");
}
}
}
// define contract
public interface PayloadStrategy {
public void process();
}
// payload context
public class PayloadContext {
PayloadStrategy strategy;
public void setContext(PayloadStrategy payloadStrategy) {
this.strategy = payloadStrategy;
}
public void processPayload() {
strategy.process();
}
}
// parameterized (PayloadA or PayloadB) payload run method
PayloadContext context = new PayloadContext();
context.setContext(new PayloadA());
context.processPayload();