我正在尝试使用RabbitMQ并根据不同的消息,应该调用不同的工具。
我将消息格式设置为JSON,并且有一个字段" callType",它的值是类名实现一个公共接口。例如,所有实现都具有实现接口"任务",并且我实现了" TaskImp1"," TaskImp2"," TaskImp3"。
所以代码应该像
if (callType=="TaskImp1")
((Task)TaskImp1).runTask()
if (callType=="TaskImp2")
((Task)TaskImp2).runTask()
if (callType=="TaskImp3")
((Task)TaskImp3).runTask()
但它可以更灵活吗?如果以后我开发一个新的" TaskImp4",我不想更改调用代码,是否有可能让java自动选择正确的实现,因为callType实际上是类的名称实施
答案 0 :(得分:1)
是的,例如,通过Java反射(What is reflection and why is it useful?)。虽然反射有性能成本(Java Reflection Performance)
答案 1 :(得分:0)
当然:将您的Task实例放在地图中:
private Map<String, Task> tasksByName = new HashMap<>();
...
tasksByName.put("TaskImp1", new TaskImp1());
tasksByName.put("TaskImp2", new TaskImp2());
tasksByName.put("TaskImp3", new TaskImp3());
...
String callType = message.getCallType();
Task task = tasksByName.get(callType);
task.runTask();
答案 2 :(得分:0)
您有机会在此处使用策略。因此对于例如你可以这样做:
public class MyTask {
private Task task;
public MyTask(Task task) {
this.task = task;
}
public void doSomething() {
task.runTask();
}
public static void main(String args[]) {
MyTask task = new MyTask(new TaskImpl1());//or even you could use setTask() api to inject task at runtime rather than doing cast on compile time.
task.doSomething();
task = new MyTask(new TaskImpl2());
task.doSomething();
task = new MyTask(new TaskImpl3());
task.doSomething();
}
}
通过这种方式,您可以使代码可扩展。明天,如果你有taskImpl4,你可以独立编码并注入MyTask,甚至不用触及MyTask类实现。
答案 3 :(得分:0)
正如@ovdsrn已经说过你可以使用反射。简单的例子就是(关键是getTask
静态方法。另外,请注意,当您使用Class.forName
时,必须为您的班级指定整个&#34;路径&#34;(包) )
// ITask.java
package main;
public interface ITask {
void doSomething();
}
// Task1.java
package main;
public class Task1 implements ITask {
@Override
public void doSomething() {
System.out.println("Task1");
}
}
// Task2.java
package main;
public class Task2 implements ITask {
@Override
public void doSomething() {
System.out.println("Task2");
}
}
// main
package main;
public class JavaTest {
private static ITask getTask(String name) {
try {
Class<?> cls = Class.forName(name);
Object clsInstance = (Object) cls.newInstance();
return (ITask)clsInstance;
} catch (Exception e) { // you can handle here only specific exceptions
return null;
}
}
public static void main(String[] args) {
String name = args.length > 0 ? args[0] : "Task2";
ITask task = getTask("main." + name);
if (task != null) {
task.doSomething();
}
else {
System.out.println("can not make instance of class: " + name);
}
}
}