如何在单个构建器类中拥有多个构建器模式?

joh*_*ohn 5 java multithreading design-patterns thread-safety builder-pattern

我有两种来自上游的有效负载:它是PayloadAPayloadB

PayloadA包含很多字段:

createTimestamp
sentTimestamp
schemaId
eventId
producerId
guid
deviceId
langId
sessionId
Run Code Online (Sandbox Code Playgroud)

PayloadB包含很多字段:

createTimestamp
sentTimestamp
schemaId
eventId
producerId
eventType
payloadVersion
creationDate
expirationSeconds
payload
Run Code Online (Sandbox Code Playgroud)

所以前 5 个字段是它们之间共同的。一般来说,他们会有更多的领域。

我想为此创建一个线程安全的构建器模式。那么我是否应该拥有一个Payload构建器模式类,其中包含来自两个有效负载的所有字段?或者我应该在另一个构建器类中拥有PayloadAPayloadB构建器模式类,并且和 的Payload公共字段将成为类的一部分?PayloadAPayloadBPayload

针对此类问题制定构建器模式的最佳方法是什么?假设PayloadA构建器模式deviceId是必填字段。对于PayloadB构建器模式来说eventType是必填字段。

Pra*_*ane 2

我建议在这里使用静态嵌套构建器(第 2 项)模式。

这是你可以做的

  1. 创建具有公共属性的abstractPayload
  2. 创建PayloadAPayloadB扩展每个Payload静态嵌套。Builder
  3. 让使用/构造这些对象的方法来处理线程安全(不需要Builder线程安全)。

有效载荷

public abstract class Payload {

    private String createTimestamp;
    private String sentTimestamp;
    private String schemaId;
    private String eventId;
    private String producerId;

    //getters, setters, equals, hashcode, toString, compareTo, etc.
}
Run Code Online (Sandbox Code Playgroud)

PayloadA(PayloadB 类似)

class PayloadA extends Payload {
    private String guid;
    private String deviceId;
    private String langId;
    private String sessionId;

    private PayloadA() {
        //avoid direct instantiation
    }

    public static class Builder {

        private String guid;
        private String deviceId;
        private String langId;
        private String sessionId;

        public Builder setLangId(String langId) {
            this.langId = langId;
            return this;
        }

        public Builder(String deviceId) {
            //validations
            this.deviceId = deviceId;
        }

        public PayloadA build() {
            //validations
            return new PayloadA();
        }

        //other setters returning this Builder
    }
}
Run Code Online (Sandbox Code Playgroud)

用法(从上游数据构造适当的有效负载

public Payload constructPayload(final Data data) {

    //implement any thread safety mechanism as requirdhere. 
    // synchronized is just for explanatory purposes
    synchronized (data) {
        if (data.getType().equals("PayloadA")) {
            return new PayloadA.Builder(data.getDeviceId())
                    //.setGuid("someGuid")
                    //other setters
                    .build();
        } else {
            return new PayloadB.Builder(data.getEventType())
                    //.setCreationDate("someCreationDate")
                    // other setters
                    .build();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助。