【问题标题】:How to have multiple builder pattern in a single builder class?如何在单个构建器类中有多个构建器模式?
【发布时间】:2016-12-06 00:48:51
【问题描述】:

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

PayloadA 包含这么多字段:

createTimestamp
sentTimestamp
schemaId
eventId
producerId
guid
deviceId
langId
sessionId

PayloadB 包含这么多字段:

createTimestamp
sentTimestamp
schemaId
eventId
producerId
eventType
payloadVersion
creationDate
expirationSeconds
payload

所以前 5 个字段在它们之间是通用的。而且一般他们会有更多的字段。

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

为此类问题制作构建器模式的最佳方法是什么。假设PayloadA builder 模式deviceId 是必填字段。对于PayloadB builder 模式eventType 是必填字段。

【问题讨论】:

标签: java multithreading design-patterns thread-safety builder-pattern


【解决方案1】:

我建议在这里使用static nested builder (item 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.
}

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
    }
}

使用(从上游数据构造适当的Payload

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();
        }
    }
}

希望这会有所帮助。

【讨论】:

  • 这看起来很有希望。现在假设 Payload 类中是否有一个字段基于 PayloadA 或 PayloadB 类的少数字段派生,无论它们是否已设置。我们将如何做到这一点?如果我们创建一个大型构建器模式 Payload 类,然后在构造函数中我们可以检查该字段是否已设置,然后根据该字段派生该变量的值,这是可能的。
  • @david 一个大建设者的问题是,如果你设置 PayloadA 的一个属性和 PayloadB 的一个属性,你最终会建造什么?
猜你喜欢
  • 2017-08-09
  • 2021-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-07
  • 2021-01-03
  • 1970-01-01
相关资源
最近更新 更多