Mono - Reactor, a pozbycie się ifów

Mono - Reactor, a pozbycie się ifów
WE
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 53
0

Cześć, otóż mam metodę

Kopiuj
 @Override
 @SneakyThrows
    public Publisher<ContainsResult> contains(Path filePath)
    {
        return Mono.fromSupplier(() -> takeFilesByPath(filePath.toString()))
                .filter(files -> !files.isEmpty())
                .map(result -> ContainsResult.FILE_IS_NOT_PRESENT)
                .defaultIfEmpty(ContainsResult.PRESENT)
                .onErrorReturn(ContainsResult.COULD_NOT_CHECK_PRESENCE);
    }

która zwraca 3 możliwe opcje, teraz mam metodę put, która ma uploadować plik w zależności od containsa:

Kopiuj
@Override
    public Publisher<PutResult> put(Path filePath, OutputStream outputStream) {
        return Mono.from(contains(filePath))
             ...
    }

i metodę

Kopiuj
PutResult considerContainsResultForPut(ContainsResult containsResult, Path filePath, OutputStream outputStream)
    {
        switch(containsResult)
        {
            case FILE_IS_NOT_PRESENT:
                uploadFile(filePath, outputStream);
                return PutResult.SUCCESS;
            case PRESENT:
                uploadFile(filePath, outputStream);
                return PutResult.FILE_OVERWRITTEN;
            default:
                return PutResult.COULD_NOT_CREATE_FILE;
        }

    }

No, ale z metody considerContainsResultForPut wyszedł potwór, który w ogóle nijak się ma do SRP.. Więc jak to rozdzielić? Najlepiej jakoś streamami z reactora aby to zrobić funkcyjnie. Z góry dzięki!

Shalom
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Space: the final frontier
  • Postów: 26433
0

Strategia, jeśli bardzo musisz :) Więc zamiast zwracać te twoje ContainsResult.PRESENT zwracaj obiekt z logiką i jakimś interfejsem który pasuje do wszystkich przypadków a w considerContainsResultForPut po prostu wywołaj metodę na tym obiekcie. Wtedy masz polimorfizm i nie ma znaczenia jaki "typ" tam masz. Na oko jakieś BiFunction po prostu ci tam będzie pasować ;]

WE
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 53
0

Sęk w tym, że moje contains() jest określone przez interfejs z góry i musi to zwracać.

Shalom
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Space: the final frontier
  • Postów: 26433
0

No to nic nie wyczarujesz ;] Możesz sobie najwyżej zrobić mapę enum -> obiekt i potem robić tylko mapa.get(enum).call(cośam), jakby to był Kotlin i jakieś SealedClass, no ale w czystej javie nie da się tu wiele zrobić.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.