java - 基于字符串的调度,无需反射或在多个位置编写代码

标签 java string dynamic dispatch

我正在开发一个框架,其中我们有任务的概念。希望很多人都会编写任务,为此他们只需要实现 Task 接口(interface)即可。任务需要通过其名称触发,这意味着需要在某个地方有一个任务名称->任务类的中央注册表。目前我正在使用 Enum 来执行此操作,但这需要任务实现者为他们实现的每个任务将代码添加到 Enum 中,这很糟糕。

我提出的另一个选项是通过反射搜索实现 Task 接口(interface)的所有类并从那里注册它们。这也让我觉得很恶心,我觉得必须有更好的方法。

如果静态初始化器不需要在运行之前至少引用该类一次,那么它就是完美的。

注释是另一种选择,但它们需要更多的反射工作,或者如果我们要进行编译时代码生成来创建调度程序,则需要更改构建过程。

还有更简单的想法吗?

<小时/>

下面是我现在正在做的事情的简单版本,以给出我想要的控制流的想法(为了简单起见,将其分解为单个类):

class Disp {
    interface Task {
        public String doTask();
    }

    static class HelloTask implements Task {
        public String doTask() {
            return "Hello";
        }
    }

    static class ByeTask implements Task {
        public String doTask() {
            return "Bye";
        }
    }

    static class TaskDispatcher {
        static enum Tasks {
            Hello {
                Task getTask() {
                    return new HelloTask();
                }
            },
            Bye {
                Task getTask() {
                    return new ByeTask();
                }
            };
            abstract Task getTask();
        };

        public static Task getTask(String taskName) {
            return Tasks.valueOf(taskName).getTask();
        }
    }

    public static void main(String[] args) {
        System.out.println("Hello task says: "+TaskDispatcher.getTask("Hello").doTask());
        System.out.println("Bye task says: "+TaskDispatcher.getTask("Bye").doTask());
    }

}

如果注册(例如)HelloTask 的代码只能存在于 HelloTask 内部,而不必泄漏到 TaskDispatcher 中(就像在实际项目中一样,这些是多个不同的文件),那就更好了

最佳答案

不要害怕使用框架!使用Spring,只需几行代码即可。每个 Task 都必须被注释(它不必是来自 Spring 的 @Service),并且您在调度程序中所要做的就是(在引导上下文并启用组件扫描之后):

class TaskDispatcher {
    @Autowired
    List<Task> tasks;

    //...
}

Spring 将自动查找 CLASSPATH 上的所有 Task 并为您注入(inject)它们。您可以使用 bean/类名称作为标识符或任何您想要的内容。

关于java - 基于字符串的调度,无需反射或在多个位置编写代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13109538/

相关文章:

JAVA——原始类型 VS 对象类型

java - 多种类型的相同接口(interface)

java - 在 Android Activity 中显示气球提示

arrays - 如何定义接受数组或字符串的 Ruby 方法?

php - Javascript Tabber 重新加载

java - 如何将字母数字字符串分成数字和字母

python - 替换输入 Python 的缺失值

html - 为什么在提交表单后带引号的值被读取为空白?

c++ - 使用 new 时变量被覆盖

arrays - Matlab数组的动态切片