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));