Я работаю над проектом, использующим Java и Spring Boot, который обрабатывает несколько разных типов сообщений из одной и той же очереди. Каждое сообщение обрабатывается в зависимости от типа сообщения с использованием реализации MessageProcessingService
абстрактного класса для каждого типа сообщения.
На данный момент у нас 5 разных типов сообщений, приходящих к одному и тому же потребителю. Мы используем ту же очередь, потому что мы используем групповые политики в JMS, и каждый тип сообщения имеет тот же бизнес-ключ, что и групповая политика.
Итак, в итоге мы получаем, что каждый раз, когда требование требует получения нового к типу сообщения мы добавляем новую реализацию MessageProcessingService
и другую зависимость к объекту-потребителю. Я хочу найти лучшую стратегию, чтобы выборочно выбирать обработку сообщений
Вот пример, аналогичный тому, что мы делаем. Я не гарантирую, что синтаксис является компилируемым или синтаксически совершенным, просто демонстрируя проблему. Обратите внимание, что все сообщения разрешаются вокруг человека
Потребитель:
@Component
public class PersonMessageConsumer {
private MessageProcessingService<HeightUpdate> heightUpdateMessageProcessingService;
private MessageProcessingService<WeightUpdate> weightUpdateMessageProcessingService;
private MessageProcessingService<NameUpdate> nameUpdateMessageProcessingService;
private MessageProcessingService<ShowSizeUpdate> shoeSizeUpdateMessageProcessingService;
public PersonMessageConsumer(
MessageProcessingService<HeightUpdate> heightUpdateMessageProcessingService,
MessageProcessingService<WeightUpdate> weightUpdateMessageProcessingService,
MessageProcessingService<NameUpdate> nameUpdateMessageProcessingService,
MessageProcessingService<ShowSizeUpdate> shoeSizeUpdateMessageProcessingService) {
this.heightUpdateMessageProcessingService = heightUpdateMessageProcessingService;
this.weightUpdateMessageProcessingService = weightUpdateMessageProcessingService;
this.nameUpdateMessageProcessingService = nameUpdateMessageProcessingService;
this.shoeSizeUpdateMessageProcessingService = shoeSizeUpdateMessageProcessingService;
}
@JmsListener(destination = "${queueName}")
public void receiveMessage(TextMessage message) {
String messageType = message.getHeader("MessageType");
switch (messageType) {
case "HeightUpdate":
heightUpdateMessageProcessingService.processMessage(message.getText());
return;
case "WeightUpdate":
weightUpdateMessageProcessingServivce.processMessage(message.getText());
return;
// And other message types
default:
throw new UnknownMessageTypeException(messageType);
}
}
Пример сообщения POJO
public class HeightUpdate implements PersonMessage {
@Getter
@Setter
private int height;
}
Интерфейс PersonMessage
public interface PersonMessage {
int getPersonId();
}
MessageProcessingService
public abstract class MessageProcessingService<T extends PersonMessage> {
public void processMessage(String messageText) {
//Common message processing, we do some more involved work here but just as a simple example
T message = new ObjectMapper.readValue(messageText, getClassType());
Person person = personRepository.load(message.getPersonId());
Person originalPerson = person.deepCopy();
processMessageLogic(person, message);
if (originalPerson.isDifferentFrom(person)) {
personRespository.update(person);
}
}
protected abstract void processMessageLogic(Person person, T message);
protected abstract Class getClassType();
}
Пример реализации абстрактного класса
@Service("heightUpdateMessageProcessingService")
public class HeightUpdateMessageProcessingService extends MessageProcessingService<HeightUpdate> {
@Override
protected void processMessageLogic(Person person, HeightUpdate update) {
person.setHeight(update.getHeight());
}
@Override
protected Class getMessageType() {
return HeightUpdate.getClass();
}
}
Так что мой вопрос в том, есть ли лучший шаблон проектирования или способ его кодирования в java и пружине, которая немного проще чистить и поддерживать и помнить SOLID принципы