프로젝트 중 하나에서 사용중인 빌더 클래스가 있습니다.오래된 빌더를 복제하여 새 빌더 객체를 만드는 방법은 무엇입니까?
- 아래 클래스를 기반으로 작성자로
metricA
이 있다고 가정 해 봅니다. - 나는
metricB
이metricA
거기에 이미 있던 모든 값을 포함하도록metricA
를 복제하여metricA
을 기반으로 새 빌더metricB
을 확인해야합니다.
MetricHolder
의 생성자에서 이미 설정된 필드에 기초하여 일부 필드를 직접 초기화합니다.
clientTypeOrPayId
-이 입력란을 초기화하고 있습니다.payId
이 있으면이 값을 설정하거나clientType
으로 설정합니다.clientKey
-이 필드는 동일한 생성자에서 초기화됩니다.- 그리고 가장 중요한 것은
clientPayload
맵에 몇 가지 필수 입력란을 넣을 예정입니다. 나는 그것을 할 올바른 방법이 무엇인지 확신하지 못합니다. 하지만is_clientid
과is_deviceid
을지도에 추가해야합니다. (일반적으로 저는 더 많은 필드를 추가하고 있습니다). - 그리고 마지막으로 생성자에서 대기 시간 차이를 계산하여 다른 시스템으로 보냅니다. 다음은
내 클래스 :
public final class MetricHolder {
private final String clientId;
private final String deviceId;
private final String payId;
private final String clientType;
private final String clientTypeOrPayId;
private final Schema schema;
private final String schemaId;
private final String clientKey;
private final Map<String, String> clientPayload;
private final Record record;
private final long clientCreateTimestamp;
private final long clientSentTimestamp;
private MetricHolder(Builder builder) {
this.payId = builder.payId;
this.siteId = builder.siteId;
this.clientType = builder.clientType;
this.clientId = builder.clientId;
this.deviceId = builder.deviceId;
this.schema = builder.schema;
this.schemaId = builder.schemaId;
// populating all the required fields in the map and make it immutable
// not sure whether this is right?
builder.clientPayload.put("is_clientid", (clientId == null) ? "false" : "true");
builder.clientPayload.put("is_deviceid", (clientId == null) ? "true" : "false");
this.clientPayload = Collections.unmodifiableMap(builder.clientPayload);
this.clientTypeOrPayId = Strings.isNullOrEmpty(payId) ? clientType : payId;
this.record = builder.record;
this.clientKey = "process:" + System.currentTimeMillis() + ":"
+ ((clientId == null) ? deviceId : clientId);
this.clientCreateTimestamp = builder.clientCreateTimestamp;
this.clientSentTimestamp = builder.clientSentTimestamp;
// this will be called twice while cloning
// what is the right way to do this then?
SendData.getInstance().insert(clientTypeOrPayId,
System.currentTimeMillis() - clientCreateTimestamp);
SendData.getInstance().insert(clientTypeOrPayId,
System.currentTimeMillis() - clientSentTimestamp);
}
public static class Builder {
private final Record record;
private Schema schema;
private String schemaId;
private String clientId;
private String deviceId;
private String payId;
private String clientType;
private Map<String, String> clientPayload;
private long clientCreateTimestamp;
private long clientSentTimestamp;
// this is for cloning
public Builder(MetricHolder packet) {
this.record = packet.record;
this.schema = packet.schema;
this.schemaId = packet.schemaId;
this.clientId = packet.clientId;
this.deviceId = packet.deviceId;
this.payId = packet.payId;
this.clientType = packet.clientType;
// make a new map and check whether mandatory fields are present already or not
// and if they are present don't add it again.
this.clientPayload = new HashMap<>();
for (Map.Entry<String, String> entry : packet.clientPayload.entrySet()) {
if (!("is_clientid".equals(entry.getKey()) || "is_deviceid".equals(entry.getKey())) {
this.clientPayload.put(entry.getKey(), entry.getValue());
}
}
this.clientCreateTimestamp = packet.clientCreateTimestamp;
this.clientSentTimestamp = packet.clientSentTimestamp;
}
public Builder(Record record) {
this.record = record;
}
public Builder setSchema(Schema schema) {
this.schema = schema;
return this;
}
public Builder setSchemaId(String schemaId) {
this.schemaId = schemaId;
return this;
}
public Builder setClientId(String clientId) {
this.clientId = clientId;
return this;
}
public Builder setDeviceId(String deviceId) {
this.deviceId = deviceId;
return this;
}
public Builder setPayId(String payId) {
this.payId = payId;
return this;
}
public Builder setClientType(String clientType) {
this.clientType = clientType;
return this;
}
public Builder setClientPayload(Map<String, String> payload) {
this.clientPayload = payload;
return this;
}
public Builder setClientCreateTimestamp(long clientCreateTimestamp) {
this.clientCreateTimestamp = clientCreateTimestamp;
return this;
}
public Builder setClientSentTimestamp(long clientSentTimestamp) {
this.clientSentTimestamp = clientSentTimestamp;
return this;
}
public MetricHolder build() {
return new MetricHolder(this);
}
}
// getters
}
질문 : - :
MetricHolder metricA = new MetricHolder.Builder(record).setClientId("123456").setDeviceId("abcdefhg")
. setPayId("98765").setClientPayload(payloadMapHolder).setClientCreateTimestamp(createTimestamp)
.setClientSentTimestamp(sentTimestamp).build();
지금이 내가를 복제하는 방법이다 아래
내가 metricA
빌더 객체를 만드는 방법이다 metricA
나중에 다른 모든 코드를 얻을 때 코드에 객체가 있습니다. 같은 DS는 다음과 같습니다 :의 MetricHolder
생성자 내 SendData.getInstance()
라인이 두 번 호출됩니다 모든
- 첫째 : 지금이 문제를 볼
MetricHolder metricB = new MetricHolder.Builder(metricA).setSchema(schema).setSchemaId("345").build();
. 먼저
metricA
을 만들고 두 번째를 만들 때metricB
을metricA
으로 복제하면됩니다. 하지만 난 한 번metricA
빌더 개체를 만들려고 전화하고 싶은거야? 어떻게하면 가능합니까? - 두 번째로, 내가 채우는 방법은
MetricHolder
생성자에서 두 개의 필수 입력란을 가진지도가 나에게 보이지 않는다. 같은 일을하는 다른 더 좋은 방법이 있습니까?
은 내가 metricA
를 복제하고있는 방법은 metricB
빌더 객체를 만들기 위해 때문에 전체 문제가 일어나고있는 것 같아요? 이 작업을 수행하는 가장 좋은 방법은 무엇입니까? 나는 위의 두 가지를 성취하고자하지만 옳은 방법으로하고 싶다.
불필요한 내용이 많기 때문에 질문이 명확하지 않습니다 (관련성이없는 분야 및 설정자 등). 코드의 핵심 부분이 더 분명해 지도록 [mcve]로 옮길 수 있습니까? –