Как избежать кода дерева if-else?

У меня есть контроллер отдыха, который включает метод для поиска книг в зависимости от параметров "title" и "author".

Не могли бы вы дать мне подсказку, как избавиться от конструкции if-else? Сейчас это не сложно, но в будущем число параметров может увеличиться, что приведет к путанице.

    @GetMapping
    public ResponseEntity<List<Book>> searchBooksByTitleAndAuthor(
            @RequestParam(value = "title", required = false) String title,
            @RequestParam(value = "author", required = false) String author) {

        if (title == null && author == null) {
            log.info("Empty request");
            return new ResponseEntity<>(HttpStatus.NO_CONTENT);
        } else if (title != null && author == null) {
            log.info("Retrieving books by title");
            List<Book> books = bookService.getBooksByTitle(title);
            if (books.isEmpty()) {
                log.info("No books with this title");
                return new ResponseEntity<>(HttpStatus.NO_CONTENT);
            }
            return new ResponseEntity<>(books, HttpStatus.OK);
        } else if (author != null && title == null) {
            List<Book> books = bookService.getBooksByTitle(title);
            if (books.isEmpty()) {
                log.info("No books with this title");
                return new ResponseEntity<>(HttpStatus.NO_CONTENT);
            }
            return new ResponseEntity<>(books, HttpStatus.OK);
        } else {
            List<Book> books = bookService.getBooksByTitleAndAuthor(title, author);
            if (books.isEmpty()) {
                log.info("No books with matching this title and author");
                return new ResponseEntity<>(HttpStatus.NO_CONTENT);
            }
            return new ResponseEntity<>(books, HttpStatus.OK);
        }

    }
4 голоса | спросил Pavel 27 PMpFri, 27 Apr 2018 17:29:16 +030029Friday 2018, 17:29:16

6 ответов


0
Поскольку ваш план состоит в том, чтобы в конечном итоге поддерживать больше параметров, вам лучше всего заглянуть в класс Hibernate ---- +: = 0 =: + ---- .Это позволяет динамически создавать запросы.Он не будет избегать операторов ---- +: = 1 =: + ---- , но будет избегать операторов ---- +: = 2 =: + ---- и сделает его довольно простымподдержка новых параметров.На вашем уровне хранилища /DAO:Это имеет некоторые заметные преимущества:Для поддержки нового параметра вам просто нужно добавить свой параметр в контроллер, затем передать параметр в хранилище и добавить параметр в этот блок.В конечном итоге вы можете сделать свой вид настраиваемым, например:Тем не менее, есть некоторые недостатки, наиболее очевидным из которых является то, что это зависит от строковых значений для ссылки на ваши свойства.Если имя вашего свойства изменится (обратите внимание, что это свойство POJO, а не имя столбца БД), тогда этот код нужно будет изменить.Тем не менее, я бы сказал, что это очень редкая ситуация, за исключением самых новых новых проектов, где схемы базы данных все еще находятся в движении, и после того, как схемы базы данных установлены, этот недостаток редко вызывает проблемы.Другой совет: как только вы нажмете определенное количество параметров, передаваемых в (например, 4-5), создайте объект параметров, чтобы обернуть ваши параметры в один красивый объект, который можно обойти.
ответил Brian 27 PMpFri, 27 Apr 2018 17:59:10 +030059Friday 2018, 17:59:10
0
Я бы порекомендовал спецификацию или Querydsl .Он основан на модели /модели, управляемой доменом, а реализация основана на критериях JPA, которые обеспечивают гибкость в построении запросов.Вот пример (не проверено, но вы должны получить общее представление).BookSpecificationsФабричный класс для динамического создания спецификаций.Обратите внимание, что использование постоянных значений, которые были сгенерированы во время компиляции из классов Entity, является более подходящим подходом.Yo может ссылаться на атрибуты сущности с помощью ---- +: = 1 =: + ---- или ---- +: = 2 =: + ---- вместо использования некоторых ---- +:= 3 =: + ---- не проверяется во время компиляции с фактической моделью сущности, такой как «автор» или «заголовок».BookControllerНа стороне контроллера вы должны избегать сокращения на минимальном уровне логики и отдавать предпочтение делегированию обработки классу обслуживания, который создаст требуемую спецификацию и передаст ее в хранилище.BookServiceВся логика здесь (модульные тесты должны быть сосредоточены здесь).Добавить новый атрибут сущности в поиск очень просто.Добавьте параметр в метод и в поток, который проверяет, заполнен ли хотя бы критерий поиска, а затем добавьте новый вызов в цепочку ---- +: = 6 =: + ---- :BookRepositoryПоследний шаг: сделайте ваш ---- +: = 8 =: + ---- интерфейс расширяет ---- +: = 9 =: + ----, чтобы иметь возможность вызывать ---- +: = 10 =: + ---- методы, принимающие ---- +: = 11 =: + ---- параметры, такие как:Это должно быть хорошо:Обратите внимание, что если может быть запрошено много атрибутов объекта, использование более динамичного подхода может быть интересным:Но у этого есть недостаток, чтобы отложить обнаружение ошибок кодирования.Действительно, ошибки в спецификации здания (например: тип значения не совместимы) могут быть обнаружены только во время выполнения.
ответил davidxxx 27 PMpFri, 27 Apr 2018 18:24:37 +030024Friday 2018, 18:24:37
0
Я бы только написал это:Я бы оставил ---- +: = 1 =: + ---- создание и ---- +: = 2 =: + ---- управление Spring.Что касается ---- +: = 3 =: + ---- или управления пустыми значениями, я бы оставил это для службы или запроса к базе данных, который следует.Кроме того, параметры, которые вы записали в аннотации RequestParam, являются значениями по умолчанию и могут быть упрощены.И наконец, зачем вам регистрировать все запросы?В чем смысл?Если вы стремитесь к производству, ваш информационный журнал будет рассылаться по многочисленным запросам, а деловая информация в любом случае не относится к техническим журналам.
ответил Adrien Brunelat 27 PMpFri, 27 Apr 2018 17:41:01 +030041Friday 2018, 17:41:01
0
Существует не очень хорошее решение для этого.Если бы я был вами, я бы рефакторинг это как:С этим решением вы будете лечить один раз ответ.Один советЕсли ни один параметр не отправлен, верните Неверный запрос о том, что для этой службы требуется хотя бы один параметр.
ответил Victor 27 PMpFri, 27 Apr 2018 17:56:02 +030056Friday 2018, 17:56:02
0
Небольшое вложение может помочь.Это сведет к минимуму повторяющиеся тесты.Некоторый код:Мне нравится ответ Брайана, но я бы никогда не рекомендовал использовать Hibernate.MyBatis также поддерживает условные предложения where.
ответил DwB 27 PMpFri, 27 Apr 2018 18:03:10 +030003Friday 2018, 18:03:10
0
Вот идея.Код может потребовать некоторой работы, в частности, я не знаю, можете ли вы использовать статическую карту, но в Spring у вас, вероятно, все равно есть синглтон.Если вы добавляете новый аргумент, вы просто добавляете новый искатель книг.Нет, если заявления.Я бы переместил ---- +: = 1 =: + ---- в ---- +: = 2 =: + ---- , но я не хочу менять ваши операторы регистрации.В противном случае это немного упростит поиск.Метод ---- +: = 3 =: + ----, конечно, можно изменить, реализация не важна.Он должен просто сопоставить входные комбинации с уникальными ключами.Предложенный подход обрабатывает до 64 аргументов, которые могут быть нулевыми /не нулевыми эффективно.
ответил ewramner 27 PMpFri, 27 Apr 2018 22:59:51 +030059Friday 2018, 22:59:51

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132