gpt4 book ai didi

java - 如何避免静态方法中的长 switch/case block

转载 作者:行者123 更新时间:2023-11-30 01:56:02 26 4
gpt4 key购买 nike

假设我有很长的 switch/case block ,这让我内心说“它看起来不太好”

                        switch (option) {
case ERROR:
doSomething();
break;
case SUCCESS:
doSomething();
break;
case WARNING:
doSomething();
break;
case SUCCESS_WITH_WARNING:
doSomething();
break;
case SUCCESS_WITH_ERROR:
doSomething();
break;
case FATAL:
doSomething();
break;
case INFO:
doSomething();
break;
default:
break;
}

请记住,我们始终可以添加更多枚举等。假设 case block 中的方法正在将某些内容打印到控制台。所以它们只是void

我试图使用访问者,但似乎有更好的选择,所以对于访问者来说,它看起来像这样:

public enum ImportOption {

SUCCEEDED{

@Override
public void accept(ImportOptionVisitor visitor) {
visitor.visitSucceededImport();
}

},
FAILED{

@Override
public void accept(ImportOptionVisitor visitor) {
visitor.visitFailedImport();
}

},
WARNING{

@Override
public void accept(ImportOptionVisitor visitor) {
visitor.visitWarningImport();
}

};

public abstract void accept(ImportOption.ImportOptionVisitor visitor);

public interface ImportOptionVisitor{
void visitSucceededImport();

void visitFailedImport();

void visitWarningImport();

}

而不是我们得到的开关:

                        option.accept(new ImportOptionVisitor() {

@Override
public void visitSucceededImport() {
// TODO Auto-generated method stub

}

@Override
public void visitFailedImport() {
// TODO Auto-generated method stub

}

@Override
public void visitWarningImport() {
// TODO Auto-generated method stub

}

但即使对于像 100 个枚举这样的长开关,它也似乎有些夸张。我读了一些关于命令模式的内容。但我不确定如何实现。有什么想法如何进行替换开关并使代码更具可读性等吗?

好的,更多信息。此代码在 Utils 类中实现,需要此开关 block 的方法如下所示:

public static void monitorDirectory(String zipDir, ImportOption option) {
String dirPath = FILE_PATH_TO_QUEUES_DIR + File.separator + zipDir;

try {
WatchService watchService = FileSystems.getDefault().newWatchService();

Path path = Paths.get(dirPath);
path.register(watchService, StandardWatchEventKinds.ENTRY_CREATE);

WatchKey key;
while ((key = watchService.take()) != null) {
for (WatchEvent<?> event : key.pollEvents()) {
String fileName = event.context().toString();
if (fileName.substring(fileName.lastIndexOf('.'), fileName.length()).equals(".7z")) {
//switch block here

break;
}
}
key.reset();
}
}
catch (IOException | InterruptedException e) {
e.printStackTrace();
}

它是监视目录,当 .7z 文件出现在那里时,它将根据 ImportOption 枚举开始处理该文件。该方法的用法为:Utils.monitorDirectory。所以我从不创建包含此方法的对象的实例(所以也许这是此代码的问题)

最佳答案

有很多方法可以解决这个问题。我提出了两个在可读性等方面相似的选项。

选项 1

根据您提供的信息(并假设您的每个 doSomething() 正在做不同的事情),我只会维护一个包含每个选项启动方法的映射。我在这里假设选项位于枚举中,但如果选项是整数或字符串,则同样的原则适用。

private static final EnumMap<ExitCode, Runnable> runOnOption = new EnumMap<> (ExitCode.class);

static {
runOnOption.put(ERROR, () -> LOG.error("an error occurred"));
runOnOption.put(SUCCESS, () -> LOG.info("success"));
runOnOption.put(FATAL, this::runOnFatal);
}

private static void runOnFatal() {
//more complex recovery code
}

那么你的主要方法就变成了:

Runnable r = runOnOption(option);
if (r == null) throw new AssertionError("Missing option: " + option);
r.run();
<小时/>

选项 2

另一种方法是将行为直接放在枚举中:

public enum ExitCode {
ERROR(() -> LOG.error("an error occured")),
SUCCESS(() -> LOG.info("success")),
FATAL(() -> {
//more complex code here
};

private final Runnable r;
ExitCode(Runnable r) { this.r = r; }

public void log() { r.run(); }
}

你的主要代码变成:

option.log();

关于java - 如何避免静态方法中的长 switch/case block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54478590/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com