Использование одной реализации сопоставления для нескольких служб - PullRequest
0 голосов
/ 15 октября 2019

Я определяю интерфейс для всех моих компонентов mapper, которые извлекают значения, используя xpath из полей xml. В качестве входных данных используется полезная нагрузка, преобразованная в качестве документа, а также обернутая торговая модель, возвращающая то же самое с заполненным полем:

interface Mapper {
    Model<Trade> map(Document document, Model<Trade> model);
}

Я определяю один родительский класс как абстракцию для дочерних классов, чтобы предоставить выражение xpath:

abstract class TradeMapper implements Mapper {
    abstract String getXpathExpression();
}

Реализация одного из картографов как компонента Spring:

@Component
class QuantityMapper extends TradeMapper {
    @Override
    public Model<Trade> map(Document document, Model<Trade> model) {
        //implementation logic to get qty and populate the trade model
        //return the same trade model with qty field populates
        return model(model)
                .quantity(qty);
                 .build();
    }

    @Override
    String getXpathExpression() {
        return "XXX";
    }
}

@Component
class IdMapper extends TradeMapper {
    @Override
    public Model<Trade> map(Document document, Model<Trade> model) {
        //implementation logic to get id and populate the trade model
    }
}

В моем приложении я получаю два типа сделок. Допустим, initial и actual. Оба они должны быть преобразованы в модель Trade в определенный момент жизненного цикла события. Для initial я передаю Message, который затем преобразуется в строковое сообщение -> в тип документа ->, а затем с помощью картографов строит объект Trade для дальнейшей обработки. Это все хорошо.

@Service
class TradeRequestService {
    @Autowired
    private List<TradeMapper> mappers;

    void callback(Model<Message> model) {
        String message = model.getPayload(model);
        Document document = getDocument(message);
        mappers.forEach(tradeMapper -> tradeMapper.map(document, model));
    }

    private Document getDocument(String message) {
        return XmlUtils.toDoc(message);
    }
}

Моя проблема в точке входа и для сообщения типа actual.

/**
 * Message Entry Point
 */
@Service
class MessageReceiver {
    @Autowired
    private List<TradeMapper> mappers;

    void callback(String message) {
        if (message.contains("initial")) {
            return model.withPayload(new Message(message)); //callback in TradeRequestService then receives this model for conversion
        } else if (message.contains("actual")) {
            // derive id from String
        } else {
            return null;
        }
    }

}

В моем приложении мне нужно уже получить сообщение типа Id для actual, используя IdMapper на уровне обслуживания MessageReceiver перед модельюпередается в TradeRequestService обратный вызов. id требуется в точке входа для получения некоторой метаинформации перед обработкой последующих обратных вызовов событий.

Я изо всех сил пытаюсь преобразовать сообщение типа actual в точке входа в Document и с помощью IdMapper вывести Id в виде строки, а контракт - Document. Как я могу реструктурировать код, чтобы получить Id из полезной нагрузки String в точке входа? Должно ли преобразование в Document и Id mapping перейти на общий интерфейс? Будем весьма благодарны за некоторые идеи или предложения о том, какой шаблон я могу использовать в этом примере или в примерах кода.

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