找到优雅的方式来包装可运行方法并将其作为java中的函数传递

问题描述 投票:0回答:1

我使用的是 java 11,假设我有多个可运行方法,除了参数数量之外,它们的结构都相同:如示例中所示:

private Runnable deleteIndex(String targetIndex) {
        return () -> {
            try {
                iIndexerManagementService.deleteIndex(targetIndex);
            } catch (Exception e) {
                log.error("Cannot perform delete:", e);
            }
        };
    }
    
    
private Runnable deleteDataBySource(String targetIndex, String source) {
        return () -> {
            try {
                indexerDocumentService.deleteBySource(targetIndex, source);
            } catch (Exception e) {
                log.error("Cannot perform delete:", e);
            }
        };
    }
    
    
private Runnable createDeleteTaskByScanID(String targetIndex, String scandId, String source) {
        return () -> {
            try {
                indexerDocumentService.deleteByScanId(targetIndex, scandId, source);
            } catch (Exception e) {
                log.error("Cannot perform delete:", e);
            }
        };
} .... 
  and more ....

后来我在每个可运行方法上都像这里一样使用它:

    public void submitDeleteIndexTask(String targetIndex) {
       Optional.ofNullable(syncControlRepository.findByName(CATALOG_ENTITY_TYPE_KEYWORD))
                        .ifPresent(strategy -> {
                            Future<?> future =  uploadersExecutor.submit(deleteIndex(targetIndex));
                            if (featureFlagEnabled && config.isTestProfile()) {
                                try {
                                    future.get(1, TimeUnit.MINUTES);
                                } catch (Exception e) {
                                    log.error("Cannot wait on thread block:", e);
                                }
                            }
                    });
            } 
.... and more

我工作完美。

但是我想找到更好的优雅的方法来不在类中保存大量可运行的方法,因为它可能会更多。 我的目的是创建 1 个通用的可运行包装器,以便能够传递任何类型的函数,因此当我使用它时,我将仅传递函数本身和要调用的参数。

我是这么想的,但我不确定它是否正确

// generic runnable wrapper to pass any function

    public Runnable runAsync(Function foo, Object o) {
        return () -> {
            try {
                foo.apply(o);
            } catch (Exception e) {
                log.error("Cannot perform delete:", e);
            }
        };
    }

然后它应该是一种能够接收函数以适应可运行方法的通用方法:

public void runGeneralAsync(... HERE PASS FUNCTION ..??. ) {
        Optional.ofNullable(syncControlRepository.findByName(CATALOG_ENTITY_TYPE_KEYWORD))
                .ifPresent(strategy -> {
                    Future<?> future =  uploadersExecutor.submit(runAsync(....FUNCTOIN... ?? ));
                    if (featureFlagEnabled && config.isTestProfile()) {
                        try {
                            future.get(1, TimeUnit.MINUTES);
                        } catch (Exception e) {
                            log.error("Cannot wait on thread block:", e);
                        }
                    }
            });
    }

请指教

java java-8 java-11 runnable
1个回答
3
投票

您所要求的等同于“字符串类型”/动态,并且从根本上来说与Java不同。你可能认为你想要这个;你不知道。如果你尝试的话,整个 Java 生态系统将在每一步中与你作斗争。

注意:你的

runGeneralAsync
非常糟糕 - 你真的在这里滥用
Optional
。该代码是一种冗长的说法:查找一个事物,如果它确实存在,则执行此操作,如果不存在,则默默地不执行任何操作。除了啰嗦(
if
没有任何问题!)之外,“什么都不做”是一个可怕的后备方案。可怕的含义是:名称或设置中的一个错误意味着什么也不会发生,因此,您将花费几个小时来追踪该错误。 NPE 需要 1 分钟。如果您编写的代码无法理解
null
的发生,那就写它吧。如果 null 确实发生,您想要该异常,这样您就知道在哪里修复问题。

无论如何:

相反,

Runnable
本身就是答案。将 lambda 包裹在 lambda 中。

你正在想这样的事情:

// API:
public void runGeneralAsync(String methodName, Object... args) {
  // Lots of reflective shenanigans to find it.
  // Lots of issues with dealing with exceptions -
  // what if the method name does not exist? What if the wrong amount
  // of args were passed? Or the wrong type? Or there is an overload?

  // .. and then of course code to stick it all into an executor.submit
}

// usage:

runGeneralAsync("deleteIndexTask", "my-index");

但是你想做的是这样的:

public void runGeneralAsync(Runnable task) {
  uploadersExecutor.submit(runAsync(....));
}

// usage:

runGeneralAsync(() -> deleteIndex("my-index"));

根据需要,你可能想用

Callable
代替这里的
Runnable
(你可以归还东西,也可以扔东西)。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.