Java 在方法中使用空检查组合任务
我有以下方法,它检查不同的方法并根据该方法返回任务(Java 在方法中使用空检查组合任务,java,Java,我有以下方法,它检查不同的方法并根据该方法返回任务(checkTask1()-checkTask7()): 第1版: public Task getTask() { Task t = null; t = checkTask1(); if (t == null) t = checkTask2(); if (t == null) t = checkTask3(); if (t == null) t = checkTask
checkTask1()
-checkTask7()
):
第1版:
public Task getTask() {
Task t = null;
t = checkTask1();
if (t == null) t = checkTask2();
if (t == null) t = checkTask3();
if (t == null) t = checkTask4();
if (t == null) t = checkTask5();
if (t == null) t = checkTask6();
if (t == null) t = checkTask7();
return t != null ? t : new Task();
}
每个checkTask
-方法只返回一个依赖任务,如果不应创建此任务,则返回null,例如checkTask1()
:
但是,我想知道是否有更好的代码结构或方法来实现上述功能。可能使用Java功能接口(生产者、消费者)还是更简单?重复的空检查有点难看。拥有大量名为
foo1
,foo2
,fooN
的方法几乎总是一种反模式和设计味道。在您的情况下,这可以很容易地解决
将checkTask
方法重构为一个:
private Task checkTask(int i) {
if (taskEnabled[i - 1]) {
return new Task(i, "myTask" + i);
}
return null;
}
将taskabled
更改为boolean
s的数组:
private boolean[] taskEnabled;
最后重构getTask
方法:
public Task getTask() {
Task t = null;
int i = 1;
while (t == null && i <= taskEnabled.length) {
t = checkTask(i);
i++;
}
return t != null ? t : new Task();
}
公共任务getTask(){
任务t=null;
int i=1;
而(t==null&&i如何创建这样的方法:
Task get(Supplier<Task>... suppliers) {
for(Supplier<Task> supplier : suppliers) {
Task task = supplier.get();
if(task != null) {
return task;
}
}
return new Task();
}
由于它使用varargs数组,您可以传递任意多个供应商
s,但是我同意每个任务都有一个方法似乎是一个反模式。建议重新考虑此设计
关于第一个解决方案,由于通用varargs,它可能会发出可能的堆污染
警告。要克服这一问题,您可以使用列表
而不是varargs:
Task get(List<Supplier<Task>> suppliers) {
//...
}
Task get = get(List.of(this::checkTask1, this::checkTask2));
任务获取(列出供应商){
//...
}
Task get=get(List.of(this::checkTask1,this::checkTask2));
你能告诉我们检查任务%n%()
做什么吗?@ruohola我用检查任务%n%()更新了这个问题。对不起,是我的错。它不能像你上面的那样重构,因为`返回新任务(1,“myTask1”);`只是一个例子。每个任务的构造都非常特殊,不仅涉及文本“myTask1”,而且还涉及与实际任务相关的更多属性。我在问题中明确指出了。有N个名为foo1、foo2…fooN的方法。fooN几乎总是一个反模式。
。是的,你是对的。。这些东西应该是重构的返回到foo
接口,实现了类foo1,foo2..fooN.Nice solution。但是,我有3个问题..1.问题:我从任务get(Supplier…suppliers)的方法体中得到警告类型安全:通过varargs参数suppliers
潜在堆污染
。我可以安全地忽略它吗?3.问题:你说:每个任务的一个方法似乎是一个反模式
。你能通过重构我的示例来给出一个解决方案,避免这个反模式吗?根据3.问题:我当然只能使用一个方法,如果..否则,我会做很多。但是我以前有过这个方法,而且我的方法很长。所以我将其拆分为更小的方法,现在我想合成结果..您的方法似乎不错..但是..编译器警告不太好..1.检查我编辑的答案如何消除警告。2.我不知道什么是OrderAdvice
。从MCVE的代码中,它不应该引发警告。3.创建接口和多个实现-每个任务一个?那么你的代码就更容易扩展-当然这取决于你的任务有多少不同。4.这是一个供应商列表,所以我不确定你说的null
值是什么意思。
Task task = get(this::checkTask1, this::checkTask2, this::checkTask3); //pass as many tasks as you want. Note that order is important.
Task get(List<Supplier<Task>> suppliers) {
//...
}
Task get = get(List.of(this::checkTask1, this::checkTask2));