如何解决Java静态构建类似于IntStream
我的目标是提供一个类来构建功能链,以在之后执行某些任务。到目前为止,这是我能想到的
函数类
public class Loop {
private final int from;
private final int to;
private Loop(int from,int to) {
this.from = from;
this.to = to;
}
public static Loop from(int from) {
return new Loop(from,0);
}
public static Loop to(int to) {
return new Loop(0,to);
}
public void execute(Executable executable) {
for (int i = from; i < to; i++) {
executable.execute();
}
}
}
可执行接口
@FunctionalInterface
public interface Executable {
void execute();
}
它可以用于一个参数(从或到),如
Loop.to(10).execute(() -> {});
但是我希望它能对多个参数起作用
Loop.from(5).to(10).execute(() -> {});
我该如何实现?同样,我不确定带有一个冗余参数的static from和static to方法是否适合Loop类。
解决方法
最好使用from
的静态变体和具有相同名称的非静态变体,但是不支持。参数或名称必须不同。
因此,我将私有构造函数公开,并添加第二个无参数构造函数,以便调用可以变为:
new Loop().from(5).to(10).execute(...)
new Loop(5,10).execute(...)
为此,from
和to
不再必须是静态的。然后,您必须确定方法是否使Loop
实例发生突变,或者方法是否返回新对象:
public Loop from(int from) {
return new Loop(from,to);
}
public Loop to(int to) {
return new Loop(from,to);
}
或
public Loop from(int from) {
this.from = from; // no longer final
return this;
}
public Loop to(int to) {
this.to = to; // no longer final
return this;
}
如果要进一步进行操作,可以将类重命名为LoopBuilder
并创建一个build()
方法,该方法返回一个Loop
,该字段具有以前的字段,但没有{{1 }}和from
方法,只是to
方法:
execute
通话将变为
public static class Loop {
private final int from;
private final int to;
public Loop(int from,int to) {
this.from = from;
this.to = to;
}
public void execute(Executable executable) {
for (int i = from; i < to; i++) {
executable.execute();
}
}
public static LoopBuilder builder() {
return new LoopBuilder();
}
}
public static class LoopBuilder {
private int from;
private int to;
public LoopBuilder from(int from) {
this.from = from;
return this;
}
public LoopBuilder to(int to) {
this.to = to;
return this;
}
public Loop build() {
return new Loop(from,to);
}
}
,
一个人可以采取几种方法。解决方案越复杂,它们通常变得越复杂。让我们从一个简单的解决方案开始。
public class Loop {
private final int from;
private final int to;
private Loop(Builder builder) {
this.from = builder.from();
this.to = builder.to();
}
public static Builder from(int from) {
return new Builder().from(from);
}
public static Builder to(int to) {
return new Builder().to(to);
}
public void execute(Runnable executable) {
for (int i = from; i < to; i++) {
executable.run();
}
}
public static class Builder {
private int from = 0;
private Integer to = null;
private Builder() {}
public Builder from(int from) {
this.from = from;
return this;
}
private int from() {
return from;
}
public Builder to(int to) {
this.to = to;
return this;
}
private int to() {
return to;
}
public void execute(Runnable runnable) {
Objects.requireNonNull(runnable);
new Loop(this).execute(runnable);
}
}
}
这已经足够了。但是,例如,我们可以多次调用from(...)
或to(...)
。如果我们只允许一次调用from(...)
,而之后只允许调用to(...)
,那么我们需要定义更多类型。我们可以通过添加接口LoopFromSetBuilder
,LoopToSetBuilder
和LoopAllSetBuilder
来实现:
interface LoopFromSetBuilder {
LoopAllSetBuilder to(int to);
}
interface LoopToSetBuilder {
LoopAllSetBuilder from(int from);
}
interface LoopAllSetBuilder {
void execute(Runnable runnable);
}
对方法Loop
进行了一些调整
class Loop {
...
public static LoopFromSetBuilder from(int from) {
return new Builder().from(from);
}
public static LoopToSetBuilder to(int to) {
return new Builder().to(to);
}
...
}
并让Builder
实现这些接口:
public static class Builder implements LoopFromSetBuilder,LoopToSetBuilder,LoopAllSetBuilder {
...
}
我们消除了用户多次呼叫from(...)
和to(...)
的可能性。
我没有构建那些“复杂的”流畅API的进一步经验,但是我认为构建这样的API的过程可能会非常痛苦。对于一些小示例,如此处所示,我们也许可以拒绝设置相同的可变多重时间,但是使用更多参数(可能的状态-因此-接口似乎按2^n
的顺序看起来很混乱,其中{ {1}}是字段数...是的。
如果有人赞成我的答案,那么也应该考虑赞成Luk2302's answer,因为我的答案的第一个解决方案与Luk2302的解决方案非常相似,而Luk2302的答案早于我的发布。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。