gpt4 book ai didi

java - 如何使用具有不可变结果和扩展接口(interface)的 fluent-interface 实现构建器模式?

转载 作者:行者123 更新时间:2023-12-04 05:46:30 24 4
gpt4 key购买 nike

我想实现一个具有流畅界面的构建器。

要求

为了使事情变得更加困难,还有两个额外的要求:

  • 我希望返回的对象是不可变的,以便它可以按如下方式使用,并且接口(interface)应该在派生接口(interface)中可扩展:
    ConcreteBuilder b1 = builder().setValue(1);
    ConcreteBuilder b2 = b1.setValue(2);

    ComplexObject o1 = b1.build();
    o1.getValue(); // should return 1

    ComplexObject o2 = b2.build();
    o2.getValue(); // should return 2

    首先是一个有待讨论的问题:构建器是否应该是不可变的,以便它具有上述语义? (Jonathan 中的 How to create an immutable builder of an immutable class that contains a set? 简要评论过)
  • 构建器接口(interface)应该是可扩展的:
    interface Builder<T extends Builder<T>> {
    T setValue(int v);
    }

    interfacte BuilderEx<T extends BuilderEx<T>> {
    T someOtherOpp();
    }

    (它使用 Eamonn McManus 1 所描述的自引用泛型)

  • 执行

    为了满足第一个要求,AbstractBuilder 的实现类似于 How to create an immutable builder of an immutable class that contains a set? 中的实现。 :
    class AbstractBuilder<T extends Builder<T>> implements Builder<T> {
    T setValue(final int v) {
    return castToConcrete(new AbstractBuilder<T>() {
    // with build() overridden to use v
    }
    }
    }
    castToConcrete应该类似于 self() 1getThis() 2 : 转换 Builder<T>ConcreteBuilderConcreteBuilderEx取决于 T .问题是如何实现 castToConcrete
    由于构建器方法创建新实例,因此覆盖 getThis 的方法在 ConcreteBuilder不起作用。使用“仿函数” 3提供给 AbstractBuilder 的构造函数并存储在字段中可以转换 Builder<T>T .添加以下字段(它使用 Guava 库 3AbstractBuilder :
    Function<Builder<T>, T> castToConcrete;

    问题

    我当前的 castToConcrete 的实现变得非常丑陋:
  • 这是一个 if-else树上 instanceof
  • input instanceof Builder而不是 input instanceof BuilderEx一个包装类,需要在 BuilderEx 中定义所有方法,转发Builder中的至input并为其他人执行默认或零操作。
  • input instanceof BuilderEx它将输入转换为 ConcreteBuilderEx即使 input可能不是 ConcreteBuilderEx 的实际实例而是 AbstractBuilderEx 的匿名子类的一个实例(希望这可行。)[由 OP 编辑​​]不起作用:我们需要每个接口(interface)的包装器[/edit]

  • 有什么更好/更清洁的方法来做到这一点?

    最佳答案

    干净的方法是不使用 AbstractBuilder但是为您需要构建的每种类型创建一个特定的构建器。通过使构建器方法可读并针对您尝试构建的对象进行定制,您可以获得流畅的界面。如果您需要创建大量构建器,您可以使用代码生成,但这些方法设计得不太好。

    关于java - 如何使用具有不可变结果和扩展接口(interface)的 fluent-interface 实现构建器模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10619483/

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