2015-10-08 2 views
0

Программа, над которой я работаю, имеет распределенную архитектуру, точнее шаблон брокера-агента. Брокер отправит сообщения своему соответствующему агенту, чтобы сообщить агенту выполнить задачу. Каждое отправленное сообщение содержит информацию о целевой задаче (имя задачи, свойства конфигурации, необходимые для выполнения задачи и т. Д.). В моем коде каждая задача на стороне агента реализуется в отдельном классе. Как:Лучшая практика для связывания создания экземпляра класса сообщения и целевого класса

public class Task1 {} 
public class Task2 {} 
public class Task3 {} 
... 

сообщения в формате JSON, как:

{ 
    "taskName": "Task1", // put the class name here 
    "config": { 

    } 
} 

Так что мне нужно, чтобы связать сообщение, посланное от брокера с правильной задачи в стороне агента.

Я знаю один способ поставить имя класса целевой задачи в сообщении, так что агент может создать экземпляр этого класса задач по имени задачи, извлеченное из сообщения с помощью отражений, как:

Class.forName(className).getConstructor(String.class).newInstance(arg); 

Я хочу знать, какая наилучшая практика для реализации этой ассоциации. Количество задач растет, и я думаю, что написать строку легко, чтобы делать ошибки и не просто поддерживать.

ответ

1

Если вы говорите об именах классов, вы даже можете подумать о сериализации объектов задачи и их отправке напрямую. Это, вероятно, проще, чем ваш подход к отражению (хотя и более жесткий).

Но обычно вы не нуждаетесь в такой связи между Брокер и Агентом. Брокер должен знать, какие типы задач есть и как описать задачу таким образом, чтобы все понимали (например, в JSON). Он не должен/не должен знать, как Агент реализует задачу. Или даже на каком языке агент написан. (Это не значит, что это плохая идея для определения имен задач в месте, которое является общим для обеих базовых кодов).

Таким образом, вам остается найти хороший способ создания объектов (или методов вызова) внутри вашего агент на основе некоторой строки. А общее решение, что некоторая форма фабричной модели, как: http://alvinalexander.com/java/java-factory-pattern-example - также полезно: а Map<String, Factory> как

interface Task { 
    void doSomething(); 
} 

interface Factory { 
    Task makeTask(String taskDescription); 
} 

Map<String, Factory> taskMap = new HashMap<>(); 

void init() { 
    taskMap.put("sayHello", new Factory() { 
     @Override 
     public Task makeTask(String taskDescription) { 
      return new Task() { 
       @Override 
       public void doSomething() { 
        System.out.println("Hello" + taskDescription); 
       } 
      }; 
     } 
    }); 
} 

void onTask(String taskName, String taskDescription) { 
    Factory factory = taskMap.get(taskName); 
    if (factory == null) { 
     System.out.println("Unknown task: " + taskName); 
    } 
    Task task = factory.makeTask(taskDescription); 

    // execute task somewhere 
    new Thread(task::doSomething).start(); 
} 

http://ideone.com/We5FZk

И если вы хотите его фантазия рассматривать аннотации магии отражения на основе. Зависит от количества классов задач. Чем больше усилий выкладываете в автоматическое решение, которое скрывает от вас сложность.

Например, выше Map может быть заполнено автоматически, добавив class path scanning для классов нужного типа с некоторой аннотацией, содержащей строки. Или вы можете позволить некоторой структуре DI внедрить все, что нужно для перехода на карту. DI в крупных проектах обычно решает такие проблемы действительно хорошо: https://softwareengineering.stackexchange.com/questions/188030/how-to-use-dependency-injection-in-conjunction-with-the-factory-pattern

И, помимо написания собственной системы распространения, вы, вероятно, можете использовать существующие. (И повторное использование, а не переосмысление - это лучшая практика). Может быть http://www.typesafe.com/activator/template/akka-distributed-workers или более общий http://twitter.github.io/finagle/ работать в вашем контексте. Но есть слишком много других распространенных вещей с открытым исходным кодом, которые охватывают разные аспекты, чтобы назвать все интересные.

+0

Очень информативный ответ! Простой пример кода и рекомендуемые статьи! Натуральное заводское решение достаточно простое, что я предпочитаю.У меня есть около 4 типов задач, в которых каждый тип имеет одну и ту же конфигурацию задач. В каждом типе имеется около 4-5 точных задач. Таким образом, общее количество задач относительно велико. – qingl97