首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java Fluent包装器

Java Fluent包装器
EN

Code Review用户
提问于 2020-05-17 00:58:44
回答 4查看 165关注 0票数 1

我的直觉告诉我这是糟糕的实践,所以,我想我会要求一些反馈。

这里的目标是在不使用反射的情况下为任何类伪造一个流畅的API设计,同时尽可能保持它的美观。如果我使用反射,我只会使用jOOR

不需要对空检查进行评论。为了简单起见,我在这篇文章中省略了它们。

类:

代码语言:javascript
复制
public final class Fluent<T> {
  private final T object;

  public Fluent(final T object) {
    this.object = object;
  }

  public Fluent<T> with(final Consumer<T> consumer) {
    consumer.accept(object);

    return this;
  }

  public T get() {
    return object;
  }
}

示例:

代码语言:javascript
复制
final MenuItem item = new Fluent<>(new MenuItem("Foo"))
                                   .with(o -> o.setAccelerator(accelerator))
                                   .with(o -> o.setOnAction(this::callback)).get();
EN

回答 4

Code Review用户

发布于 2020-05-17 11:11:43

是的,您的实现是可靠的和possible...however的,从一开始就使用它是没有任何意义的,至少对于您的示例是这样的。

代码语言:javascript
复制
final MenuItem item = new Fluent<>(new MenuItem("Foo"))
                                   .with(o -> o.setAccelerator(accelerator))
                                   .with(o -> o.setOnAction(this::callback)).get();

与以下情况相比:

代码语言:javascript
复制
final MenuItem item = new MenuItem("foot");
item.setAccelerator(accelerator);
item.setOnAction(this::callback);

这是较少的代码类型,更容易输入,更容易阅读。

如果您想成为一点more...uh...fancy,那么至少可以对非最终类使用双大括号初始化:

代码语言:javascript
复制
final MenuItem item = new MenuItem("foot") {{
    setAccelerator(accelerator);
    setOnAction(this::callback);
}};

不需要对空检查进行评论。为了简单起见,我在这篇文章中省略了它们。

下一次请不要。

票数 3
EN

Code Review用户

发布于 2020-05-18 08:25:24

我觉得您只想在每次调用之前和之后调用链中的setters,以避免编写item.;,而不是真正拥有一个流畅的界面。

这是否确实使您的代码更流畅、更易于维护,还是您引入了混淆了未来阅读它的人的外国概念?你还记得那个代码在6个月内会做些什么吗?

我想说你的直觉就在这里。你在跳圈是为了没有多大的进步。

票数 2
EN

Code Review用户

发布于 2020-05-17 13:17:26

我为一个Fluent Builder编写了类似问题的代码,它还接受Consumer作为参数,允许调用方提供一组先前确定的不透明修改。在菜单示例中,这可能是:

代码语言:javascript
复制
new Fluent<>(new Menu("File")))
  .with(o -> o.setAccelerator(accelerator))
  .with(contextSensitiveMenuItem)

这就需要一个varargs调用,因为不透明项在数量上是可变的。

代码语言:javascript
复制
public Fluent<T> with(Consumer<T>... consumers) {
  for (consumer in consumers) {
    consumer.accept(object);
  }
  return this;
}

一般说来,我不确定final参数在这个上下文中有多有用。THe编译器会自己解决这个问题。

票数 0
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/242436

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档