Как устранить нулевые аргументы без избыточных кодов

#java #parameters #null

#java #параметры #null

Вопрос:

Например:

 getBooks(author, title)
  
  • Если разрешить автору быть нулевым, вернет все книги с определенным названием
  • Если разрешить значение title равным null, вернет все книги для конкретного автора
  • Если разрешить обоим быть нулевыми, вернет все книги независимо от названия или автора

Чтобы устранить это, выполните следующие функции:

 getBooks(author) 
getBooks(title)  
getBooks(author, title)  
getBooks()
  

В новых функциях могут быть избыточные коды, или если мы сгруппируем эти избыточные коды в функцию, мы все равно получим функцию с нулевыми параметрами. Какой лучший способ справиться с этим — без избыточного кода и без нулевых параметров?

Ответ №1:

Не перегружайте так сильно:

 getBooksByAuthor(author) 
getBooksByTitle(title)  
getBooksByAuthorAndTitle(author, title)  
getBooks()
  

Обратите внимание, что это не уменьшит повторное использование кода: эти методы могут повторно использовать / совместно использовать любой код, который им нужен в их реализациях

Комментарии:

1. Полностью согласен. Такого рода вещи становятся намного более очевидными, когда вы действительно начинаете использовать свой код (через TDD). Выполнение таких вызовов, как getBooks(null, false, 'author', null) кошмар обслуживания (даже в ваших тестах).

Ответ №2:

Вы можете использовать константу, чтобы указать, какой тип поиска выполнять, и проверить, был ли передан параметр (очень непроверенный и проверенный на ошибку):

 public static final int R_AUTH = 1;
public static final int R_BOOK = 2;
public static final int R_ALL = 3;

public bookSearch( int searchType, String... search )
{
    switch( searchType )
    {
        case R_AUTH:
          // search based off of (String)search[0].stringValue();
        break;
        case R_ALL:
          // load all
        break;
    }
}

bookSearch(R_ALL);
bookSearch(R_AUTH, "Poe");
  

Ответ №3:

Предполагая, что author и title являются строками, вы можете сделать следующее:

 public List getBooks(String params ...) {
    if (params.length == 0) { //search 
     //do search all books regardless of title or author
    } else if (params.length == 2 amp;amp; "cte_author".equals(params[1])) {
     //do search  by author
    } else if (params.length == 2 amp;amp; "cte_title".equals(params[1])) {
     //do search by title
    } else if (params.length == 2){
     //do search by title and book
    } else {
     //throw exception
    }
}
  

Итак, вы можете использовать этот метод следующим образом:

 getBooks();
getBooks("Gabriel Garcia Marquez", "cte_author");
getBooks("Cien anios de soledad", "cte_title");
getBooks("Gabriel Garcia Marquez","Cien anios de soledad");
  

Комментарии:

1. В любом случае я предпочитаю решение, предоставленное @Bohemian

Ответ №4:

Попробуйте этот подход:

 getAllBooks()            {return getBooks("", "");}
getBooksByAuthor(author) {return getBooks(author, "");}
getBooksByTitle(title)   {return getBooks("", title);}
getBooksByAuthorAndTitle(author, title)
{
    if(author.equals("") amp;amp; title.equals(""))
    {
        return //your book list
    }
    else if(author.equals(""))
    {
        return //a list of books with the given title
    }
    else if(title.equals(""))
    {
        return //a list of books with given author
    }
    else
    {
        return //a list of books with the given title and author
    }
}
  

Редактировать:
Обновлено, чтобы обойти двусмысленность.

Комментарии:

1. Я вижу большую проблему: getBooks(author) и getBooks(title) оба имеют одинаковую сигнатуру метода: getBooks(String str) , и поэтому компилятор или ваша логика не смогут узнать, какой из них желателен. Так что это не сработает.

2. заголовок / автор могут быть объектами. В противном случае вы правы, это проблема.

3. Возможно, но в вашем коде нет двусмысленности: они оба являются строками, и это просто не сработает.