Method '…' is too complex to analyze by data flow algorithm and method optimization

0

Mam metodę, która ustawia dane za pomocą wzorca Builder w DTO obiektu Movie. Problem polega na tym, że ta metoda jest nieco skomplikowana, a IntelliJ wyświetla ostrzeżenie o zbyt dużym skomplikowaniu.

private static Movie.Builder initMovieDto(final MovieEntity movieEntity) {
        final Movie.Builder builder = (Movie.Builder) new Movie.Builder(
                movieEntity.getTitle(),
                movieEntity.getType()
        )
                .withId(movieEntity.getId().toString());

        movieEntity.getRating().ifPresent(builder::withRating);
        movieEntity.getRating().ifPresent(ratings -> builder.withNumberOfRating(movieEntity.getRatings().size()));
        final Optional<String> locatedTitle = movieEntity.getOtherTitles().stream()
                .filter(ot -> ot.getStatus() == DataStatus.ACCEPTED)
                .map(ServiceUtils::toOtherTitleDto)
                .filter(ot -> ot.getCountry() != null
                        && ot.getCountry().getCode().equals(Locale.getDefault().getCountry()))
                .map(OtherTitle::getTitle)
                .findFirst();
        locatedTitle.ifPresent(builder::withTitleLocated);
        final Supplier<Stream<ReleaseDate>> releaseDateStream = () -> movieEntity.getReleaseDates().stream()
                .filter(ot -> ot.getStatus() == DataStatus.ACCEPTED)
                .map(ServiceUtils::toReleaseDateDto);
        Optional<ReleaseDate> releaseDate = releaseDateStream.get()
                .filter(rd -> rd.getCountry().getCode().equals(Locale.getDefault().getCountry()))
                .findFirst();
        if(releaseDate.isPresent()) {
            builder.withReleaseDate(releaseDate.get());
        } else {
            releaseDate = releaseDateStream.get()
                    .filter(rd -> movieEntity.getCountries().stream()
                            .filter(c -> c.getStatus() == DataStatus.ACCEPTED)
                            .map(ServiceUtils::toCountryDto)
                            .collect(Collectors.toList()).stream()
                            .map(Country::getCountry)
                            .collect(Collectors.toList())
                            .contains(rd.getCountry()))
                    .findFirst();
            if(releaseDate.isPresent()) {
                builder.withReleaseDate(releaseDate.get());
            } else {
                releaseDate = releaseDateStream.get().findFirst();
                builder.withReleaseDate(releaseDate.orElse(null));
            }
        }
        builder.withCountries(movieEntity.getCountries().stream().filter(c -> c.getStatus() == DataStatus.ACCEPTED).map(MovieCountryEntity::getCountry).collect(Collectors.toList()));
        builder.withLanguages(movieEntity.getLanguages().stream().filter(l -> l.getStatus() == DataStatus.ACCEPTED).map(MovieLanguageEntity::getLanguage).collect(Collectors.toList()));
        builder.withGenres(movieEntity.getGenres().stream().filter(g -> g.getStatus() == DataStatus.ACCEPTED).map(MovieGenreEntity::getGenre).collect(Collectors.toList()));
        builder.withBoxofficeCumulative(movieEntity.getBoxOffices().stream().filter(bo -> bo.getStatus() == DataStatus.ACCEPTED).map(MovieBoxOfficeEntity::getBoxOffice).reduce(BigDecimal::add).orElse(null));
        builder.withOutline(movieEntity.getOutlines().stream().filter(o -> o.getStatus() == DataStatus.ACCEPTED).map(MovieOutlineEntity::getOutline).findFirst().orElse(null));
        builder.withSummary(movieEntity.getSummaries().stream().filter(s -> s.getStatus() == DataStatus.ACCEPTED).map(MovieSummaryEntity::getSummary).findFirst().orElse(null));
        return builder;
    }

Intellij pokazuje mi ostrzeżenie

Method 'initMovieDto' is too complex to analyze by data flow algorithm less... (Ctrl+F1) 
This inspection analyzes method control and data flow to report possible conditions that are always true or false, expressions whose value is statically proven to be constant, and situations that can lead to nullability contract violations.

Co gorsza. W przyszłości jak rozwinę obiekt o nowe informacje, to ta metoda będzie jeszcze bardzie rozwinięta.
Czy macie pomysł jak zoptymalizować tą metodę? W tej metodzie muszę ustawić tak dużo danych w obiekcie DTO Movie.

1

Może najpierw podziel ten kod na osobne metody? Na razie to niezły mindfuck, zwłaszcza z tymi jednolinijkowymi streamami.

0

Się tym nie przejmuj. Intellij nie musi rozumieć wszystkiego. Ale może to być światełko ostrzegawcze, bo kod powinien być zawsze zrozumiały. Dla człowieka przynajmniej.

0

Serio IntelliJ musiał ci powiedzieć że ten kod jest zły, dam tego nie widzisz? Tego się nie da czytać w ogóle. Jeśli w with robisz cokolwiek więcej niż tylko pobranie wartości pola to zrób nową metodę z tego. A jeśli budujesz kolejne dto które jest pole to w ogóle zrób nową klasę na to.

0

No dobra, nie doczytałem, że jest też prośba o refaktoring. To dość proste. Skomplikowane twory kilkulinijkowe zastąp metodami o czytelnych nazwach. Metody mogą być nawet bardzo krótkie, a ich nazwy mogą być nawet bardzo długie. Powtarzam to za Martinem Fowlerem z książki o refaktoringu. Cel nadrzędny: kod ma być czytelny. Na przykład:

locatedTitle = titleInOriginCountryLanguage();

Ostatecznie może się udać coś takiego, że każde przypisanie do pola dto będzie pochodziło z tak ładnie opisanej metody.

1 użytkowników online, w tym zalogowanych: 0, gości: 1