Как уменьшить количество if в пользовательском десериализаторе - PullRequest
0 голосов
/ 04 мая 2019

Я проанализировал свой пользовательский десериализатор JSON с помощью SonarLint, и он говорит, что я должен уменьшить Cognitive Complexitiy с 21 до как минимум 15. Другими словами, это означает, что мне нужно много утверждений if.Мой десериализатор выглядит так:

   @Override
    public Movie deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        ObjectCodec oc = p.getCodec();
        JsonNode node = oc.readTree(p);

        Movie movie = new Movie();
        movie.setId(node.get("id").textValue());
        movie.setTitle(node.get("movieInfo").get("title").textValue());

        int identifiersSize = node.get("movieInfo").get("identifiers").size();
        String IMSC="";
        for(int i=0;i<identifiersSize;i++){
            if(node.get("movieInfo").get("identifiers").get(i).get("type").textValue().equals("IMSC")){
                IMSC = node.get("movieInfo").get("identifiers").get(i).get("identifier").textValue();
            }
        }
        if(IMSC.isEmpty()){
            IMSC = node.get("id").textValue();
        }
        movie.setIMSC(IMSC);

        if(node.get("movieInfo").has("subtitle")){
            movie.setSubtitle(node.get("movieInfo").get("subtitle").textValue());
        }

        if(node.get("movieInfo").has("publishedDate")){
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            LocalDate date;
            try {
                date = LocalDate.parse(node.get("movieInfo").get("publishedDate").asText(), formatter);
            } catch (DateTimeParseException e){
                date = LocalDate.of(node.get("movieInfo").get("publishedDate").asInt(),1,1);
            }
            movie.setPublishedDate(date);
        }


        if(node.get("movieInfo").has("publisher")){
            movie.setPublisher(node.get("movieInfo").get("publisher").textValue());
        }

        if(node.get("movieInfo").has("description")){
            movie.setDescription(node.get("movieInfo").get("description").textValue());
        }

        if(node.get("movieInfo").has("length")){
            movie.setLength(node.get("movieInfo").get("length").asInt());
        }

        if(node.get("movieInfo").has("imageLinks")){
            movie.setThumbnailUrl(node.get("movieInfo").get("imageLinks").get("thumbnail").asText());
        }

        if(node.get("movieInfo").has("language")){
            movie.setLanguage(node.get("movieInfo").get("language").asText());
        }

        if(node.get("movieInfo").has("previewLink")){
            movie.setPreviewLink(node.get("movieInfo").get("previewLink").asText());
        }

        if(node.get("movieInfo").has("ratingsCount")) {
            movie.setRatingsCount(node.get("movieInfo").get("ratingsCount").asInt());
            movie.setAverageRating(node.get("movieInfo").get("averageRating").doubleValue());
        }


        if(node.get("movieInfo").has("authors")) {
            List<String> authors= new ArrayList<>();
            int size = node.get("movieInfo").get("authors").size();
            for(int i =0;i<size;i++){
               authors.add(node.get("movieInfo").get("authors").get(i).asText());
            }
            movie.setAuthors(authors);
        }

        if(node.get("movieInfo").has("categories")) {
            List<String> categories= new ArrayList<>();
            int size = node.get("movieInfo").get("categories").size();
            for(int i =0;i<size;i++){
            categories.add(node.get("movieInfo").get("categories").get(i).asText());
            }
            movie.setCategories(categories);
        }

        return movie;
    }

Мои вопросы: есть ли лучший способ сделать это?Я хотел бы получить ноль ошибок от SonarLint.

1 Ответ

0 голосов
/ 04 мая 2019

Вы, кажется, звоните node.get("movieInfo") и node.get("id") много раз.Вы могли бы существенно упростить код, кэшируя значения этих двух вызовов в локальных переменных.

Но я не думаю, что есть хороший способ существенно сократить операторы if.(Возможно, вам удастся пересмотреть операторы if, создав таблицу лямбда-выражений, а затем итерируя «ключи» вашего узла, ища и вызывая соответствующие лямбда-выражения. Но я сомневаюсь, что это облегчит чтение кода.)

Вы можете разделить метод на под-методы и уменьшить количество if операторов на метод.Это, вероятно, сделать SonarLint счастливее, но это спорно, что делает код более читаемым.


Я хотел бы иметь нулевые ошибки от SonarLint.

1017

Это не то, что ваша цель должна быть.Очевидная цель таких инструментов, как SonarLint, - помочь вам сделать ваш код более читабельным и обслуживаемым с помощью искусственных мер сложности кода.Однако:

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