Я думаю, это связано с тем, что авторы пытаются имитировать функциональный стиль программирования, когда пользователь библиотеки может вызывать функции (процедуры, методы), но не может создавать новые объекты с помощью конструкторов. Конечно, каждая асинхронная программа - это граф объектов, и невозможно избежать создания новых объектов. Авторы решили сделать большинство классов недоступными для пользователей и вместо этого предоставили фабричные методы для создания объектов. См., Например, следующий фрагмент кода:
if (sources.length == 1) {
Publisher<? extends T> source = sources[0];
if (source instanceof Fuseable) {
return onAssembly(new FluxMapFuseable<>(from(source),
v -> combinator.apply(new Object[]{v})));
}
return onAssembly(new FluxMap<>(from(source),
v -> combinator.apply(new Object[]{v})));
}
return onAssembly(new FluxCombineLatest<>(sources,
combinator, Queues.get(prefetch), prefetch));
Классы FluxMapFuseable, FluxMap, FluxCombineLatest все являются частными для пакета. Пользователь не может создать их экземпляр, и авторам библиотеки приходится кодировать объекты создания этих классов в дополнительных методах.
Если бы библиотека была написана в объектно-ориентированном стиле, то авторы должны были бы предоставить пользователю минимальный набор ядра. классы и позволяют пользователю свободно расширять их и комбинировать объекты любым подходящим способом, а также избавиться от бремени "покрывать все комбинации всех возможностей", как писал Даг Ли на своем посте на форуме по интересам параллелизма .
Кстати, я написал асинхронную библиотеку в стиле OO (DF4J, Dataflow для Java), и она на несколько порядков короче, чем Project Reactor или Rx Java. Конечно, он не обеспечивает все, что предоставляют основные библиотеки, но обладает некоторыми уникальными функциями, такими как возможность создавать асинхронные вызовы процедур с произвольным числом асинхронных параметров.