gpt4 book ai didi

java - 如何子类化 Java 构建器类?

转载 作者:行者123 更新时间:2023-11-30 06:59:13 25 4
gpt4 key购买 nike

我有两个构建器 - PayloadAPayloadB。为了使示例更简单,我删除了许多其他字段。

  • PayloadA.Builder 构造函数将 processNamegenericRecord 作为输入参数,然后从 genericRecord 中提取一些内容。我正在对此进行验证。
  • PayloadB.Builder 构造函数还采用 processNamegenericRecord 作为输入参数,然后从 genericRecord< 中提取一些不同的内容 与上面相比。我正在这些不同的领域进行验证。

如您所见,这两个 Payload?.Builder 之间的共同点是 processNamegenericRecord、提取 oldTimestamp code> 值,然后是 isValid 方法。

下面是我的 PayloadA 类:

public final class PayloadA {
private final String clientId;
private final String deviceId;
private final String processName;
private final GenericRecord genericRecord;
private final Long oldTimestamp;

private PayloadA(Builder builder) {
this.clientId = builder.clientId;
this.deviceId = builder.deviceId;
this.processName = builder.processName;
this.genericRecord = builder.genericRecord;
this.oldTimestamp = builder.oldTimestamp;
}

public static class Builder {
private final String processName;
private final GenericRecord genericRecord;
private final String clientId;
private final String deviceId;
private final Long oldTimestamp;

public Builder(PayloadA payload) {
this.processName = payload.processName;
this.genericRecord = payload.genericRecord;
this.clientId = payload.clientId;
this.deviceId = payload.deviceId;
this.oldTimestamp = payload.oldTimestamp;
}

public Builder(String processName, GenericRecord genericRecord) {
this.processName = processName;
this.genericRecord = genericRecord;
this.clientId = (String) DataUtils.parse(genericRecord, "clientId");
this.deviceId = (String) DataUtils.parse(genericRecord, "deviceId");
this.oldTimestamp = (Long) DataUtils.parse(genericRecord, "oldTimestamp");
}

// calling this method to validate
public boolean isValid() {
return isValidClientIdDeviceId();
}

private boolean isValidClientIdDeviceId() {
// validate here
}

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

// getter here
}

下面是我的 PayloadB 类:

public final class PayloadB {
private final GenericRecord genericRecord;
private final String processName;
private final String type;
private final String datumId;
private final Long oldTimestamp;

private PayloadB(Builder builder) {
this.processName = builder.processName;
this.genericRecord = builder.genericRecord;
this.type = builder.type;
this.datumId = builder.datumId;
this.oldTimestamp = builder.oldTimestamp;
}

public static class Builder {
private final GenericRecord genericRecord;
private final String processName;
private final String type;
private final String datumId;
private final Long oldTimestamp;

public Builder(PayloadB payload) {
this.processName = payload.processName;
this.genericRecord = payload.genericRecord;
this.type = payload.type;
this.datumId = payload.datumId;
this.oldTimestamp = payload.oldTimestamp;
}

public Builder(String processName, GenericRecord genericRecord) {
this.processName = processName;
this.genericRecord = genericRecord;
this.type = (String) DataUtils.parse(genericRecord, "type");
this.datumId = (String) DataUtils.parse(genericRecord, "datumId");
this.oldTimestamp = (Long) DataUtils.parse(genericRecord, "oldTimestamp");
}

// calling this method to validate
public boolean isValid() {
return isValidType() && isValidDatumId();
}

private boolean isValidType() {
// validate here
}

private boolean isValidDatumId() {
// validate here
}

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

// getter here

}

现在有什么方法可以在这里使用抽象类的概念吗?我可以创建一个抽象类 Payload 但我的抽象类中应该包含什么内容:

public final class PayloadA extends Payload { ... }
public final class PayloadB extends Payload { ... }

然后,一旦我构建了两个构建器,我会将其传递给其他一些方法,并且我想使用 getter 访问所有字段。假设我已经构建了 PayloadA,因此我将发送到执行方法,如下所示,然后在该方法中,我想提取 PayloadA 的所有字段。同样,如果我发送 PayloadB 到执行方法,那么我想使用 getters 提取 PayloadB 类的所有字段。我怎样才能做到这一点?

private void execute(Payload payload) {

// How can I access fields of PayloadA or PayloadB
// depending on what was passe
}

最佳答案

仅当提到的字段不是巧合时才为有效负载创建一个父类(super class)。您可以在其中移动公共(public)字段和方法(但不能移动构建器)。您甚至可以为构建器创建一个父类(super class),但它可能会使代码变得过于困惑。

如果您确实需要使用有效负载父类(super class),那么您可以使用 Visitor Pattern 实现您的 execute 方法。 :

首先,您必须创建一个访问者,您可以在其中访问您的具体类:

public class PayloadVisitor {

public void visit(PayloadA payloadA) {
// use payload A here
}

public void visit(PayloadB payloadB) {
// use payload B here
}
}

然后你必须向你的父类(super class)添加一个方法来接受访问者:

public abstract class Payload {

// common fields and methods

public abstract void accept(PayloadVisitor visitor);
}

重写子类中的方法accept:

public final class PayloadA extends Payload {

// ...

@Override
public void accept(PayloadVisitor visitor) {
visitor.visit(this);
}
}

public final class PayloadB extends Payload {

// ...

@Override
public void accept(PayloadVisitor visitor) {
visitor.visit(this);
}
}

您的方法 execute 只是将调用重定向到相应的 visit 方法:

private void execute(Payload payload) {
payload.accept(new PayloadVisitor());
}

访客模式可能会令人难以承受。您还可以保持简单并使用 instanceof 来确定具体类。

关于java - 如何子类化 Java 构建器类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41237321/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com