我的直觉告诉我这是糟糕的实践,所以,我想我会要求一些反馈。
这里的目标是在不使用反射的情况下为任何类伪造一个流畅的API设计,同时尽可能保持它的美观。如果我使用反射,我只会使用jOOR。
不需要对空检查进行评论。为了简单起见,我在这篇文章中省略了它们。
类:
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;
}
}示例:
final MenuItem item = new Fluent<>(new MenuItem("Foo"))
.with(o -> o.setAccelerator(accelerator))
.with(o -> o.setOnAction(this::callback)).get();发布于 2020-05-17 11:11:43
是的,您的实现是可靠的和possible...however的,从一开始就使用它是没有任何意义的,至少对于您的示例是这样的。
final MenuItem item = new Fluent<>(new MenuItem("Foo"))
.with(o -> o.setAccelerator(accelerator))
.with(o -> o.setOnAction(this::callback)).get();与以下情况相比:
final MenuItem item = new MenuItem("foot");
item.setAccelerator(accelerator);
item.setOnAction(this::callback);这是较少的代码类型,更容易输入,更容易阅读。
如果您想成为一点more...uh...fancy,那么至少可以对非最终类使用双大括号初始化:
final MenuItem item = new MenuItem("foot") {{
setAccelerator(accelerator);
setOnAction(this::callback);
}};不需要对空检查进行评论。为了简单起见,我在这篇文章中省略了它们。
下一次请不要。
发布于 2020-05-18 08:25:24
我觉得您只想在每次调用之前和之后调用链中的setters,以避免编写item.和;,而不是真正拥有一个流畅的界面。
这是否确实使您的代码更流畅、更易于维护,还是您引入了混淆了未来阅读它的人的外国概念?你还记得那个代码在6个月内会做些什么吗?
我想说你的直觉就在这里。你在跳圈是为了没有多大的进步。
发布于 2020-05-17 13:17:26
我为一个Fluent Builder编写了类似问题的代码,它还接受Consumer作为参数,允许调用方提供一组先前确定的不透明修改。在菜单示例中,这可能是:
new Fluent<>(new Menu("File")))
.with(o -> o.setAccelerator(accelerator))
.with(contextSensitiveMenuItem)这就需要一个varargs调用,因为不透明项在数量上是可变的。
public Fluent<T> with(Consumer<T>... consumers) {
for (consumer in consumers) {
consumer.accept(object);
}
return this;
}一般说来,我不确定final参数在这个上下文中有多有用。THe编译器会自己解决这个问题。
https://codereview.stackexchange.com/questions/242436
复制相似问题