2014-11-08 5 views
0

RabbitMQ를 사용하려고하고 다른 메시지를 기반으로 여러 가지 도구를 호출해야합니다.RabbitMQ - 다른 조건에 따라 다른 구현 호출

메시지 형식을 JSON으로 설정하고 "callType"필드가 있고, 그 값은 공통 인터페이스를 구현하는 클래스 이름입니다. 예를 들어 모든 구현에는 인터페이스 "Task"가 구현되어 있고 "TaskImp1", "TaskImp2", "TaskImp3"구현이 있습니다.

그래서 코드는

if (callType=="TaskImp1") 
((Task)TaskImp1).runTask() 
if (callType=="TaskImp2") 
((Task)TaskImp2).runTask() 
if (callType=="TaskImp3") 
((Task)TaskImp3).runTask() 

처럼해야하지만 더 유연 할 수 있을까? 나중에 새 "TaskImp4"를 개발하면 호출 코드를 변경하고 싶지 않습니다. callType이 실제로 구현의 클래스 이름이므로 자바가 자동으로 올바른 구현을 선택하게 할 수 있습니까?

답변

0

은 물론이 :지도에서 작업 인스턴스를 넣어 :

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

또한, 자바 반사 ( What is reflection and why is it useful?)를 통해, 예를 들어,

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에 주입 할 수 있습니다.

0

@ovdsrn은 이미 리플렉션을 사용할 수 있다고 말했습니다. 간단한 예는 같은 것입니다 (키가 getTask 정적 방법입니다. 당신은 전체 "경로"를 지정해야합니다 Class.forName을 사용하는 경우 또한, 점에 유의하여 클래스 (패키지))

// 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"); 
     }  
    } 

// 메인

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); 
     } 
    } 
} 
관련 문제