Как преобразовать метод с аргументом потребителя в производителя? - PullRequest
0 голосов
/ 02 апреля 2020

Этот вопрос следует за предыдущим: Как конвертировать for-l oop в продюсера?

Основная задача (которая гораздо более конкретна c): Чтение текстового файла в парадигме источника

Существует SynchronousProducer * Интерфейс 1010 *, который поддерживает две операции:

public interface SynchronousProducer<ITEM> {
    /**
     * Produces the next item.
     *
     * @return produced item
     */
    ITEM next();

    /**
     * Tells if there are more items available.
     *
     * @return true if there is more items, false otherwise
     */
    boolean hasNext();
}

Потребитель спрашивает производителя, есть ли еще доступные элементы, и если ни один не входит в последовательность выключения.

Теперь следует за проблемой.

На данный момент существует объект currentProducer , реализующий следующий интерфейс:

import java.util.function.Consumer;

public interface CurrentProducer<ITEM> {
    /**
     * Feeds data sequentially into consumer
     *   by calling {@link Consumer#accept} method on each data item.
     * @param consumer data consumer
     */
    void produce(Consumer<ITEM> consumer);
}

...

// controlling code:
currentProducer.produce(consumer);

consumer.shutdown();

Задача состоит в преобразовании управляющий код в следующем:

var producer = new SynchronousProducerImpl(currentProducer);

while (producer.hasNext()) {
  consumer.accept(producer.next())
}

consumer.shutdown();

Вопрос. Учитывая currentProducer , который реализует интерфейс CurrentProducer : как написать реализацию производителя SynchronousProducer интерфейс? (Он должен обернуть currentProducer объект).

Разъяснение. От @Kayaman есть разумное количество вопросов, и, кажется, необходимо добавить некоторую ясность:

  1. Существует существующая кодовая база, которая реализует интерфейс CurrentProducer .
  2. Существует постоянный рефакторинг, направленный на инкапсуляцию параллелизма в конвейер, который схематически выглядит как что:

    pipeline
        .setProducer(producer)
        .setProcessor(processor)
        .setWriter(writer)
        .run();
    

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

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

Обновление. Кажется, что более разумный интерфейс для производителя должен быть следующим:

public interface SynchronousProducer<ITEM> {
    /**
     * Tries to produce the next item.
     *
     * @return true if item is successfully produced and false if items are exhausted
     * @throws ProductionException if item could not be produced.
     */
    boolean next() throws ProductionException;

    /**
     * Returns an item produced by {@link #next method}.
     *
     * @return item produced
     * @throws ProductionException if trying to retrieve an item that is not produced yet.
     */
    ITEM get() throws ProductionException;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...